mirror of
https://github.com/certbot/certbot.git
synced 2026-08-01 19:02:52 +02:00
Merge branch 'master' into docs-structure
This commit is contained in:
@@ -519,7 +519,11 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
addrs = set()
|
addrs = set()
|
||||||
args = self.aug.match(path + "/arg")
|
try:
|
||||||
|
args = self.aug.match(path + "/arg")
|
||||||
|
except RuntimeError:
|
||||||
|
logger.warn("Encountered a problem while parsing file: %s, skipping", path)
|
||||||
|
return None
|
||||||
for arg in args:
|
for arg in args:
|
||||||
addrs.add(obj.Addr.fromstring(self.parser.get_arg(arg)))
|
addrs.add(obj.Addr.fromstring(self.parser.get_arg(arg)))
|
||||||
is_ssl = False
|
is_ssl = False
|
||||||
@@ -533,7 +537,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||||||
if addr.get_port() == "443":
|
if addr.get_port() == "443":
|
||||||
is_ssl = True
|
is_ssl = True
|
||||||
|
|
||||||
filename = get_file_path(path)
|
filename = get_file_path(self.aug.get("/augeas/files%s/path" % get_file_path(path)))
|
||||||
if self.conf("handle-sites"):
|
if self.conf("handle-sites"):
|
||||||
is_enabled = self.is_site_enabled(filename)
|
is_enabled = self.is_site_enabled(filename)
|
||||||
else:
|
else:
|
||||||
@@ -567,6 +571,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||||||
os.path.basename(path) == "VirtualHost"]
|
os.path.basename(path) == "VirtualHost"]
|
||||||
for path in paths:
|
for path in paths:
|
||||||
new_vhost = self._create_vhost(path)
|
new_vhost = self._create_vhost(path)
|
||||||
|
if not new_vhost:
|
||||||
|
continue
|
||||||
realpath = os.path.realpath(new_vhost.filep)
|
realpath = os.path.realpath(new_vhost.filep)
|
||||||
if realpath not in vhost_paths.keys():
|
if realpath not in vhost_paths.keys():
|
||||||
vhs.append(new_vhost)
|
vhs.append(new_vhost)
|
||||||
@@ -780,7 +786,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||||||
self.aug.load()
|
self.aug.load()
|
||||||
# Get Vhost augeas path for new vhost
|
# Get Vhost augeas path for new vhost
|
||||||
vh_p = self.aug.match("/files%s//* [label()=~regexp('%s')]" %
|
vh_p = self.aug.match("/files%s//* [label()=~regexp('%s')]" %
|
||||||
(ssl_fp, parser.case_i("VirtualHost")))
|
(self._escape(ssl_fp), parser.case_i("VirtualHost")))
|
||||||
if len(vh_p) != 1:
|
if len(vh_p) != 1:
|
||||||
logger.error("Error: should only be one vhost in %s", avail_fp)
|
logger.error("Error: should only be one vhost in %s", avail_fp)
|
||||||
raise errors.PluginError("Currently, we only support "
|
raise errors.PluginError("Currently, we only support "
|
||||||
@@ -990,7 +996,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||||||
self.parser.add_dir(vh_path, "Include", self.mod_ssl_conf)
|
self.parser.add_dir(vh_path, "Include", self.mod_ssl_conf)
|
||||||
|
|
||||||
def _add_servername_alias(self, target_name, vhost):
|
def _add_servername_alias(self, target_name, vhost):
|
||||||
fp = vhost.filep
|
fp = self._escape(vhost.filep)
|
||||||
vh_p = self.aug.match("/files%s//* [label()=~regexp('%s')]" %
|
vh_p = self.aug.match("/files%s//* [label()=~regexp('%s')]" %
|
||||||
(fp, parser.case_i("VirtualHost")))
|
(fp, parser.case_i("VirtualHost")))
|
||||||
if not vh_p:
|
if not vh_p:
|
||||||
@@ -1043,6 +1049,17 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||||||
if need_to_save:
|
if need_to_save:
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
|
def _escape(self, fp):
|
||||||
|
fp = fp.replace(",", "\\,")
|
||||||
|
fp = fp.replace("[", "\\[")
|
||||||
|
fp = fp.replace("]", "\\]")
|
||||||
|
fp = fp.replace("|", "\\|")
|
||||||
|
fp = fp.replace("=", "\\=")
|
||||||
|
fp = fp.replace("(", "\\(")
|
||||||
|
fp = fp.replace(")", "\\)")
|
||||||
|
fp = fp.replace("!", "\\!")
|
||||||
|
return fp
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Enhancements
|
# Enhancements
|
||||||
######################################################################
|
######################################################################
|
||||||
@@ -1115,7 +1132,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||||||
if not use_stapling_aug_path:
|
if not use_stapling_aug_path:
|
||||||
self.parser.add_dir(ssl_vhost.path, "SSLUseStapling", "on")
|
self.parser.add_dir(ssl_vhost.path, "SSLUseStapling", "on")
|
||||||
|
|
||||||
ssl_vhost_aug_path = parser.get_aug_path(ssl_vhost.filep)
|
ssl_vhost_aug_path = self._escape(parser.get_aug_path(ssl_vhost.filep))
|
||||||
|
|
||||||
# Check if there's an existing SSLStaplingCache directive.
|
# Check if there's an existing SSLStaplingCache directive.
|
||||||
stapling_cache_aug_path = self.parser.find_dir('SSLStaplingCache',
|
stapling_cache_aug_path = self.parser.find_dir('SSLStaplingCache',
|
||||||
@@ -1372,7 +1389,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||||||
|
|
||||||
self.aug.load()
|
self.aug.load()
|
||||||
# Make a new vhost data structure and add it to the lists
|
# Make a new vhost data structure and add it to the lists
|
||||||
new_vhost = self._create_vhost(parser.get_aug_path(redirect_filepath))
|
new_vhost = self._create_vhost(parser.get_aug_path(self._escape(redirect_filepath)))
|
||||||
self.vhosts.append(new_vhost)
|
self.vhosts.append(new_vhost)
|
||||||
self._enhanced_vhosts["redirect"].add(new_vhost)
|
self._enhanced_vhosts["redirect"].add(new_vhost)
|
||||||
|
|
||||||
|
|||||||
@@ -1247,6 +1247,45 @@ class MultipleVhostsTest(util.ApacheTest):
|
|||||||
self.config.aug.match.side_effect = RuntimeError
|
self.config.aug.match.side_effect = RuntimeError
|
||||||
self.assertFalse(self.config._check_aug_version())
|
self.assertFalse(self.config._check_aug_version())
|
||||||
|
|
||||||
|
class AugeasVhostsTest(util.ApacheTest):
|
||||||
|
"""Test vhosts with illegal names dependant on augeas version."""
|
||||||
|
# pylint: disable=protected-access
|
||||||
|
|
||||||
|
def setUp(self): # pylint: disable=arguments-differ
|
||||||
|
td = "debian_apache_2_4/augeas_vhosts"
|
||||||
|
cr = "debian_apache_2_4/augeas_vhosts/apache2"
|
||||||
|
vr = "debian_apache_2_4/augeas_vhosts/apache2/sites-available"
|
||||||
|
super(AugeasVhostsTest, self).setUp(test_dir=td,
|
||||||
|
config_root=cr,
|
||||||
|
vhost_root=vr)
|
||||||
|
|
||||||
|
self.config = util.get_apache_configurator(
|
||||||
|
self.config_path, self.vhost_path, self.config_dir, self.work_dir)
|
||||||
|
self.vh_truth = util.get_vh_truth(
|
||||||
|
self.temp_dir, "debian_apache_2_4/augeas_vhosts")
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
shutil.rmtree(self.temp_dir)
|
||||||
|
shutil.rmtree(self.config_dir)
|
||||||
|
shutil.rmtree(self.work_dir)
|
||||||
|
|
||||||
|
def test_choosevhost_with_illegal_name(self):
|
||||||
|
self.config.aug = mock.MagicMock()
|
||||||
|
self.config.aug.match.side_effect = RuntimeError
|
||||||
|
path = "debian_apache_2_4/augeas_vhosts/apache2/sites-available/old,default.conf"
|
||||||
|
chosen_vhost = self.config._create_vhost(path)
|
||||||
|
self.assertEqual(None, chosen_vhost)
|
||||||
|
|
||||||
|
def test_choosevhost_works(self):
|
||||||
|
path = "debian_apache_2_4/augeas_vhosts/apache2/sites-available/old,default.conf"
|
||||||
|
chosen_vhost = self.config._create_vhost(path)
|
||||||
|
self.assertTrue(chosen_vhost == None or chosen_vhost.path == path)
|
||||||
|
|
||||||
|
@mock.patch("certbot_apache.configurator.ApacheConfigurator._create_vhost")
|
||||||
|
def test_get_vhost_continue(self, mock_vhost):
|
||||||
|
mock_vhost.return_value = None
|
||||||
|
vhs = self.config.get_virtual_hosts()
|
||||||
|
self.assertEqual([], vhs)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main() # pragma: no cover
|
unittest.main() # pragma: no cover
|
||||||
|
|||||||
Vendored
+196
@@ -0,0 +1,196 @@
|
|||||||
|
# This is the main Apache server configuration file. It contains the
|
||||||
|
# configuration directives that give the server its instructions.
|
||||||
|
# See http://httpd.apache.org/docs/2.4/ for detailed information about
|
||||||
|
# the directives and /usr/share/doc/apache2/README.Debian about Debian specific
|
||||||
|
# hints.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Summary of how the Apache 2 configuration works in Debian:
|
||||||
|
# The Apache 2 web server configuration in Debian is quite different to
|
||||||
|
# upstream's suggested way to configure the web server. This is because Debian's
|
||||||
|
# default Apache2 installation attempts to make adding and removing modules,
|
||||||
|
# virtual hosts, and extra configuration directives as flexible as possible, in
|
||||||
|
# order to make automating the changes and administering the server as easy as
|
||||||
|
# possible.
|
||||||
|
|
||||||
|
# It is split into several files forming the configuration hierarchy outlined
|
||||||
|
# below, all located in the /etc/apache2/ directory:
|
||||||
|
#
|
||||||
|
# /etc/apache2/
|
||||||
|
# |-- apache2.conf
|
||||||
|
# | `-- ports.conf
|
||||||
|
# |-- mods-enabled
|
||||||
|
# | |-- *.load
|
||||||
|
# | `-- *.conf
|
||||||
|
# |-- conf-enabled
|
||||||
|
# | `-- *.conf
|
||||||
|
# `-- sites-enabled
|
||||||
|
# `-- *.conf
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# * apache2.conf is the main configuration file (this file). It puts the pieces
|
||||||
|
# together by including all remaining configuration files when starting up the
|
||||||
|
# web server.
|
||||||
|
#
|
||||||
|
# * ports.conf is always included from the main configuration file. It is
|
||||||
|
# supposed to determine listening ports for incoming connections which can be
|
||||||
|
# customized anytime.
|
||||||
|
#
|
||||||
|
# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/
|
||||||
|
# directories contain particular configuration snippets which manage modules,
|
||||||
|
# global configuration fragments, or virtual host configurations,
|
||||||
|
# respectively.
|
||||||
|
#
|
||||||
|
# They are activated by symlinking available configuration files from their
|
||||||
|
# respective *-available/ counterparts. These should be managed by using our
|
||||||
|
# helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See
|
||||||
|
# their respective man pages for detailed information.
|
||||||
|
#
|
||||||
|
# * The binary is called apache2. Due to the use of environment variables, in
|
||||||
|
# the default configuration, apache2 needs to be started/stopped with
|
||||||
|
# /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not
|
||||||
|
# work with the default configuration.
|
||||||
|
|
||||||
|
|
||||||
|
# Global configuration
|
||||||
|
|
||||||
|
#
|
||||||
|
# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
|
||||||
|
#
|
||||||
|
Mutex file:${APACHE_LOCK_DIR} default
|
||||||
|
|
||||||
|
#
|
||||||
|
# PidFile: The file in which the server should record its process
|
||||||
|
# identification number when it starts.
|
||||||
|
# This needs to be set in /etc/apache2/envvars
|
||||||
|
#
|
||||||
|
PidFile ${APACHE_PID_FILE}
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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 5
|
||||||
|
|
||||||
|
|
||||||
|
# These need to be set in /etc/apache2/envvars
|
||||||
|
User ${APACHE_RUN_USER}
|
||||||
|
Group ${APACHE_RUN_GROUP}
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# 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 ${APACHE_LOG_DIR}/error.log
|
||||||
|
|
||||||
|
#
|
||||||
|
# LogLevel: Control the severity of messages logged to the error_log.
|
||||||
|
# Available values: trace8, ..., trace1, debug, info, notice, warn,
|
||||||
|
# error, crit, alert, emerg.
|
||||||
|
# It is also possible to configure the log level for particular modules, e.g.
|
||||||
|
# "LogLevel info ssl:warn"
|
||||||
|
#
|
||||||
|
LogLevel warn
|
||||||
|
|
||||||
|
# Include module configuration:
|
||||||
|
IncludeOptional mods-enabled/*.load
|
||||||
|
IncludeOptional mods-enabled/*.conf
|
||||||
|
|
||||||
|
# Include list of ports to listen on
|
||||||
|
Include ports.conf
|
||||||
|
|
||||||
|
|
||||||
|
# Sets the default security model of the Apache2 HTTPD server. It does
|
||||||
|
# not allow access to the root filesystem outside of /usr/share and /var/www.
|
||||||
|
# The former is used by web applications packaged in Debian,
|
||||||
|
# the latter may be used for local directories served by the web server. If
|
||||||
|
# your system is serving content from a sub-directory in /srv you must allow
|
||||||
|
# access here, or in any related virtual host.
|
||||||
|
<Directory />
|
||||||
|
Options FollowSymLinks
|
||||||
|
AllowOverride None
|
||||||
|
Require all denied
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
<Directory /usr/share>
|
||||||
|
AllowOverride None
|
||||||
|
Require all granted
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
<Directory /var/>
|
||||||
|
Options Indexes FollowSymLinks
|
||||||
|
AllowOverride None
|
||||||
|
Require all granted
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
# AccessFileName: The name of the file to look for in each directory
|
||||||
|
# for additional configuration directives. See also the AllowOverride
|
||||||
|
# directive.
|
||||||
|
#
|
||||||
|
AccessFileName .htaccess
|
||||||
|
|
||||||
|
#
|
||||||
|
# The following lines prevent .htaccess and .htpasswd files from being
|
||||||
|
# viewed by Web clients.
|
||||||
|
#
|
||||||
|
<FilesMatch "^\.ht">
|
||||||
|
Require all denied
|
||||||
|
</FilesMatch>
|
||||||
|
|
||||||
|
# The following directives define some format nicknames for use with
|
||||||
|
# a CustomLog directive.
|
||||||
|
#
|
||||||
|
# These deviate from the Common Log Format definitions in that they use %O
|
||||||
|
# (the actual bytes sent including headers) instead of %b (the size of the
|
||||||
|
# requested file), because the latter makes it impossible to detect partial
|
||||||
|
# requests.
|
||||||
|
#
|
||||||
|
# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended.
|
||||||
|
# Use mod_remoteip instead.
|
||||||
|
#
|
||||||
|
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
|
||||||
|
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
|
||||||
|
LogFormat "%h %l %u %t \"%r\" %>s %O" common
|
||||||
|
LogFormat "%{Referer}i -> %U" referer
|
||||||
|
LogFormat "%{User-agent}i" agent
|
||||||
|
|
||||||
|
# Include of directories ignores editors' and dpkg's backup files,
|
||||||
|
# see README.Debian for details.
|
||||||
|
|
||||||
|
# Include generic snippets of statements
|
||||||
|
IncludeOptional conf-enabled/*.conf
|
||||||
|
|
||||||
|
# Include the virtual host configurations:
|
||||||
|
IncludeOptional sites-enabled/*.conf
|
||||||
|
|
||||||
|
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
<VirtualHost 1.1.1.1>
|
||||||
|
|
||||||
|
ServerName invalid.net
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
# Define an access log for VirtualHosts that don't define their own logfile
|
||||||
|
CustomLog ${APACHE_LOG_DIR}/other_vhosts_access.log vhost_combined
|
||||||
|
|
||||||
|
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
# Changing the following options will not really affect the security of the
|
||||||
|
# server, but might make attacks slightly more difficult in some cases.
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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 | Minimal | Minor | Major | Prod
|
||||||
|
# where Full conveys the most information, and Prod the least.
|
||||||
|
#ServerTokens Minimal
|
||||||
|
ServerTokens OS
|
||||||
|
#ServerTokens Full
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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 Off
|
||||||
|
ServerSignature On
|
||||||
|
|
||||||
|
#
|
||||||
|
# Allow TRACE method
|
||||||
|
#
|
||||||
|
# Set to "extended" to also reflect the request body (only for testing and
|
||||||
|
# diagnostic purposes).
|
||||||
|
#
|
||||||
|
# Set to one of: On | Off | extended
|
||||||
|
TraceEnable Off
|
||||||
|
#TraceEnable On
|
||||||
|
|
||||||
|
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
<IfModule mod_alias.c>
|
||||||
|
<IfModule mod_cgi.c>
|
||||||
|
Define ENABLE_USR_LIB_CGI_BIN
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
<IfModule mod_cgid.c>
|
||||||
|
Define ENABLE_USR_LIB_CGI_BIN
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
<IfDefine ENABLE_USR_LIB_CGI_BIN>
|
||||||
|
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
|
||||||
|
<Directory "/usr/lib/cgi-bin">
|
||||||
|
AllowOverride None
|
||||||
|
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
|
||||||
|
Require all granted
|
||||||
|
</Directory>
|
||||||
|
</IfDefine>
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
|
||||||
Vendored
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../conf-available/other-vhosts-access-log.conf
|
||||||
Vendored
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../conf-available/security.conf
|
||||||
Vendored
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../conf-available/serve-cgi-bin.conf
|
||||||
Vendored
+29
@@ -0,0 +1,29 @@
|
|||||||
|
# envvars - default environment variables for apache2ctl
|
||||||
|
|
||||||
|
# this won't be correct after changing uid
|
||||||
|
unset HOME
|
||||||
|
|
||||||
|
# for supporting multiple apache2 instances
|
||||||
|
if [ "${APACHE_CONFDIR##/etc/apache2-}" != "${APACHE_CONFDIR}" ] ; then
|
||||||
|
SUFFIX="-${APACHE_CONFDIR##/etc/apache2-}"
|
||||||
|
else
|
||||||
|
SUFFIX=
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Since there is no sane way to get the parsed apache2 config in scripts, some
|
||||||
|
# settings are defined via environment variables and then used in apache2ctl,
|
||||||
|
# /etc/init.d/apache2, /etc/logrotate.d/apache2, etc.
|
||||||
|
export APACHE_RUN_USER=www-data
|
||||||
|
export APACHE_RUN_GROUP=www-data
|
||||||
|
# temporary state file location. This might be changed to /run in Wheezy+1
|
||||||
|
export APACHE_PID_FILE=/var/run/apache2/apache2$SUFFIX.pid
|
||||||
|
export APACHE_RUN_DIR=/var/run/apache2$SUFFIX
|
||||||
|
export APACHE_LOCK_DIR=/var/lock/apache2$SUFFIX
|
||||||
|
# Only /var/log/apache2 is handled by /etc/logrotate.d/apache2.
|
||||||
|
export APACHE_LOG_DIR=/var/log/apache2$SUFFIX
|
||||||
|
|
||||||
|
## The locale used by some modules like mod_dav
|
||||||
|
export LANG=C
|
||||||
|
|
||||||
|
export LANG
|
||||||
|
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
# Depends: dav_svn
|
||||||
|
<IfModule !mod_dav_svn.c>
|
||||||
|
Include mods-enabled/dav_svn.load
|
||||||
|
</IfModule>
|
||||||
|
LoadModule authz_svn_module /usr/lib/apache2/modules/mod_authz_svn.so
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
<IfModule !mod_dav.c>
|
||||||
|
LoadModule dav_module /usr/lib/apache2/modules/mod_dav.so
|
||||||
|
</IfModule>
|
||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
# dav_svn.conf - Example Subversion/Apache configuration
|
||||||
|
#
|
||||||
|
# For details and further options see the Apache user manual and
|
||||||
|
# the Subversion book.
|
||||||
|
#
|
||||||
|
# NOTE: for a setup with multiple vhosts, you will want to do this
|
||||||
|
# configuration in /etc/apache2/sites-available/*, not here.
|
||||||
|
|
||||||
|
# <Location URL> ... </Location>
|
||||||
|
# URL controls how the repository appears to the outside world.
|
||||||
|
# In this example clients access the repository as http://hostname/svn/
|
||||||
|
# Note, a literal /svn should NOT exist in your document root.
|
||||||
|
#<Location /svn>
|
||||||
|
|
||||||
|
# Uncomment this to enable the repository
|
||||||
|
#DAV svn
|
||||||
|
|
||||||
|
# Set this to the path to your repository
|
||||||
|
#SVNPath /var/lib/svn
|
||||||
|
# Alternatively, use SVNParentPath if you have multiple repositories under
|
||||||
|
# under a single directory (/var/lib/svn/repo1, /var/lib/svn/repo2, ...).
|
||||||
|
# You need either SVNPath and SVNParentPath, but not both.
|
||||||
|
#SVNParentPath /var/lib/svn
|
||||||
|
|
||||||
|
# Access control is done at 3 levels: (1) Apache authentication, via
|
||||||
|
# any of several methods. A "Basic Auth" section is commented out
|
||||||
|
# below. (2) Apache <Limit> and <LimitExcept>, also commented out
|
||||||
|
# below. (3) mod_authz_svn is a svn-specific authorization module
|
||||||
|
# which offers fine-grained read/write access control for paths
|
||||||
|
# within a repository. (The first two layers are coarse-grained; you
|
||||||
|
# can only enable/disable access to an entire repository.) Note that
|
||||||
|
# mod_authz_svn is noticeably slower than the other two layers, so if
|
||||||
|
# you don't need the fine-grained control, don't configure it.
|
||||||
|
|
||||||
|
# Basic Authentication is repository-wide. It is not secure unless
|
||||||
|
# you are using https. See the 'htpasswd' command to create and
|
||||||
|
# manage the password file - and the documentation for the
|
||||||
|
# 'auth_basic' and 'authn_file' modules, which you will need for this
|
||||||
|
# (enable them with 'a2enmod').
|
||||||
|
#AuthType Basic
|
||||||
|
#AuthName "Subversion Repository"
|
||||||
|
#AuthUserFile /etc/apache2/dav_svn.passwd
|
||||||
|
|
||||||
|
# To enable authorization via mod_authz_svn (enable that module separately):
|
||||||
|
#<IfModule mod_authz_svn.c>
|
||||||
|
#AuthzSVNAccessFile /etc/apache2/dav_svn.authz
|
||||||
|
#</IfModule>
|
||||||
|
|
||||||
|
# The following three lines allow anonymous read, but make
|
||||||
|
# committers authenticate themselves. It requires the 'authz_user'
|
||||||
|
# module (enable it with 'a2enmod').
|
||||||
|
#<LimitExcept GET PROPFIND OPTIONS REPORT>
|
||||||
|
#Require valid-user
|
||||||
|
#</LimitExcept>
|
||||||
|
|
||||||
|
#</Location>
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
# Depends: dav
|
||||||
|
<IfModule !mod_dav_svn.c>
|
||||||
|
<IfModule !mod_dav.c>
|
||||||
|
Include mods-enabled/dav.load
|
||||||
|
</IfModule>
|
||||||
|
LoadModule dav_svn_module /usr/lib/apache2/modules/mod_dav_svn.so
|
||||||
|
</IfModule>
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so
|
||||||
+89
@@ -0,0 +1,89 @@
|
|||||||
|
<IfModule mod_ssl.c>
|
||||||
|
|
||||||
|
# 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 builtin
|
||||||
|
SSLRandomSeed startup file:/dev/urandom 512
|
||||||
|
SSLRandomSeed connect builtin
|
||||||
|
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
|
||||||
|
#
|
||||||
|
AddType application/x-x509-ca-cert .crt
|
||||||
|
AddType application/x-pkcs7-crl .crl
|
||||||
|
|
||||||
|
# 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/share/apache2/ask-for-passphrase
|
||||||
|
|
||||||
|
# Inter-Process Session Cache:
|
||||||
|
# Configure the SSL Session Cache: First the mechanism
|
||||||
|
# to use and second the expiring timeout (in seconds).
|
||||||
|
# (The mechanism dbm has known memory leaks and should not be used).
|
||||||
|
#SSLSessionCache dbm:${APACHE_RUN_DIR}/ssl_scache
|
||||||
|
SSLSessionCache shmcb:${APACHE_RUN_DIR}/ssl_scache(512000)
|
||||||
|
SSLSessionCacheTimeout 300
|
||||||
|
|
||||||
|
# Semaphore:
|
||||||
|
# Configure the path to the mutual exclusion semaphore the
|
||||||
|
# SSL engine uses internally for inter-process synchronization.
|
||||||
|
# (Disabled by default, the global Mutex directive consolidates by default
|
||||||
|
# this)
|
||||||
|
#Mutex file:${APACHE_LOCK_DIR}/ssl_mutex ssl-cache
|
||||||
|
|
||||||
|
|
||||||
|
# SSL Cipher Suite:
|
||||||
|
# List the ciphers that the client is permitted to negotiate. See the
|
||||||
|
# ciphers(1) man page from the openssl package for list of all available
|
||||||
|
# options.
|
||||||
|
# Enable only secure ciphers:
|
||||||
|
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# The protocols to enable.
|
||||||
|
# Available values: all, SSLv3, TLSv1, TLSv1.1, TLSv1.2
|
||||||
|
# SSL v2 is no longer supported
|
||||||
|
SSLProtocol all
|
||||||
|
|
||||||
|
# Allow insecure renegotiation with clients which do not yet support the
|
||||||
|
# secure renegotiation protocol. Default: Off
|
||||||
|
#SSLInsecureRenegotiation on
|
||||||
|
|
||||||
|
# Whether to forbid non-SNI clients to access name based virtual hosts.
|
||||||
|
# Default: Off
|
||||||
|
#SSLStrictSNIVHostCheck On
|
||||||
|
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
# Depends: setenvif mime socache_shmcb
|
||||||
|
LoadModule ssl_module /usr/lib/apache2/modules/mod_ssl.so
|
||||||
Vendored
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../mods-available/authz_svn.load
|
||||||
Vendored
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../mods-available/dav.load
|
||||||
Vendored
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../mods-available/dav_svn.conf
|
||||||
Vendored
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../mods-available/dav_svn.load
|
||||||
Vendored
+15
@@ -0,0 +1,15 @@
|
|||||||
|
# If you just change the port or add more ports here, you will likely also
|
||||||
|
# have to change the VirtualHost statement in
|
||||||
|
# /etc/apache2/sites-enabled/000-default.conf
|
||||||
|
|
||||||
|
Listen 80
|
||||||
|
|
||||||
|
<IfModule ssl_module>
|
||||||
|
Listen 443
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
<IfModule mod_gnutls.c>
|
||||||
|
Listen 443
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
<VirtualHost *:80 [::]:80>
|
||||||
|
|
||||||
|
ServerName ip-172-30-0-17
|
||||||
|
ServerAdmin webmaster@localhost
|
||||||
|
DocumentRoot /var/www/html
|
||||||
|
|
||||||
|
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||||
|
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||||
|
|
||||||
|
</VirtualHost>
|
||||||
|
|
||||||
|
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
sites-available/certbot.conf, certbot.demo
|
||||||
|
sites-available/encryption-example.conf, encryption-example.demo
|
||||||
|
sites-available/ocsp-ssl.conf, ocspvhost.com
|
||||||
@@ -393,6 +393,8 @@ class HelpfulArgumentParser(object):
|
|||||||
("Conflicting values for displayer."
|
("Conflicting values for displayer."
|
||||||
" {0} conflicts with dialog_mode").format(arg)
|
" {0} conflicts with dialog_mode").format(arg)
|
||||||
)
|
)
|
||||||
|
elif parsed_args.verbose_count > flag_default("verbose_count"):
|
||||||
|
parsed_args.text_mode = True
|
||||||
|
|
||||||
if parsed_args.validate_hooks:
|
if parsed_args.validate_hooks:
|
||||||
hooks.validate_hooks(parsed_args)
|
hooks.validate_hooks(parsed_args)
|
||||||
|
|||||||
+54
-26
@@ -5,6 +5,7 @@ import os
|
|||||||
import signal
|
import signal
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
from certbot import errors
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -20,43 +21,62 @@ _SIGNALS = ([signal.SIGTERM] if os.name == "nt" else
|
|||||||
|
|
||||||
|
|
||||||
class ErrorHandler(object):
|
class ErrorHandler(object):
|
||||||
"""Registers functions to be called if an exception or signal occurs.
|
"""Context manager for running code that must be cleaned up on failure.
|
||||||
|
|
||||||
This class allows you to register functions that will be called when
|
The context manager allows you to register functions that will be called
|
||||||
an exception (excluding SystemExit) or signal is encountered. The
|
when an exception (excluding SystemExit) or signal is encountered. Usage:
|
||||||
class works best as a context manager. For example:
|
|
||||||
|
|
||||||
with ErrorHandler(cleanup_func):
|
handler = ErrorHandler(cleanup1_func, *cleanup1_args, **cleanup1_kwargs)
|
||||||
|
handler.register(cleanup2_func, *cleanup2_args, **cleanup2_kwargs)
|
||||||
|
|
||||||
|
with handler:
|
||||||
do_something()
|
do_something()
|
||||||
|
|
||||||
If an exception is raised out of do_something, cleanup_func will be
|
Or for one cleanup function:
|
||||||
called. The exception is not caught by the ErrorHandler. Similarly,
|
|
||||||
if a signal is encountered, cleanup_func is called followed by the
|
|
||||||
previously registered signal handler.
|
|
||||||
|
|
||||||
Every registered function is attempted to be run to completion
|
with ErrorHandler(func, args, kwargs):
|
||||||
exactly once. If a registered function raises an exception, it is
|
do_something()
|
||||||
logged and the next function is called. If a (different) handled
|
|
||||||
signal occurs while calling a registered function, it is attempted
|
If an exception is raised out of do_something, the cleanup functions will
|
||||||
to be called again by the next signal handler.
|
be called in last in first out order. Then the exception is raised.
|
||||||
|
Similarly, if a signal is encountered, the cleanup functions are called
|
||||||
|
followed by the previously received signal handler.
|
||||||
|
|
||||||
|
Each registered cleanup function is called exactly once. If a registered
|
||||||
|
function raises an exception, it is logged and the next function is called.
|
||||||
|
Signals received while the registered functions are executing are
|
||||||
|
deferred until they finish.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, func=None, *args, **kwargs):
|
def __init__(self, func=None, *args, **kwargs):
|
||||||
|
self.body_executed = False
|
||||||
self.funcs = []
|
self.funcs = []
|
||||||
self.prev_handlers = {}
|
self.prev_handlers = {}
|
||||||
|
self.received_signals = []
|
||||||
if func is not None:
|
if func is not None:
|
||||||
self.register(func, *args, **kwargs)
|
self.register(func, *args, **kwargs)
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
self.set_signal_handlers()
|
self.body_executed = False
|
||||||
|
self._set_signal_handlers()
|
||||||
|
|
||||||
def __exit__(self, exec_type, exec_value, trace):
|
def __exit__(self, exec_type, exec_value, trace):
|
||||||
|
self.body_executed = True
|
||||||
|
retval = False
|
||||||
# SystemExit is ignored to properly handle forks that don't exec
|
# SystemExit is ignored to properly handle forks that don't exec
|
||||||
if exec_type not in (None, SystemExit):
|
if exec_type in (None, SystemExit):
|
||||||
|
return retval
|
||||||
|
elif exec_type is errors.SignalExit:
|
||||||
|
logger.debug("Encountered signals: %s", self.received_signals)
|
||||||
|
retval = True
|
||||||
|
else:
|
||||||
logger.debug("Encountered exception:\n%s", "".join(
|
logger.debug("Encountered exception:\n%s", "".join(
|
||||||
traceback.format_exception(exec_type, exec_value, trace)))
|
traceback.format_exception(exec_type, exec_value, trace)))
|
||||||
self.call_registered()
|
|
||||||
self.reset_signal_handlers()
|
self._call_registered()
|
||||||
|
self._reset_signal_handlers()
|
||||||
|
self._call_signals()
|
||||||
|
return retval
|
||||||
|
|
||||||
def register(self, func, *args, **kwargs):
|
def register(self, func, *args, **kwargs):
|
||||||
"""Sets func to be called with *args and **kwargs during cleanup
|
"""Sets func to be called with *args and **kwargs during cleanup
|
||||||
@@ -66,7 +86,7 @@ class ErrorHandler(object):
|
|||||||
"""
|
"""
|
||||||
self.funcs.append(functools.partial(func, *args, **kwargs))
|
self.funcs.append(functools.partial(func, *args, **kwargs))
|
||||||
|
|
||||||
def call_registered(self):
|
def _call_registered(self):
|
||||||
"""Calls all registered functions"""
|
"""Calls all registered functions"""
|
||||||
logger.debug("Calling registered functions")
|
logger.debug("Calling registered functions")
|
||||||
while self.funcs:
|
while self.funcs:
|
||||||
@@ -77,7 +97,7 @@ class ErrorHandler(object):
|
|||||||
logger.exception(error)
|
logger.exception(error)
|
||||||
self.funcs.pop()
|
self.funcs.pop()
|
||||||
|
|
||||||
def set_signal_handlers(self):
|
def _set_signal_handlers(self):
|
||||||
"""Sets signal handlers for signals in _SIGNALS."""
|
"""Sets signal handlers for signals in _SIGNALS."""
|
||||||
for signum in _SIGNALS:
|
for signum in _SIGNALS:
|
||||||
prev_handler = signal.getsignal(signum)
|
prev_handler = signal.getsignal(signum)
|
||||||
@@ -86,19 +106,27 @@ class ErrorHandler(object):
|
|||||||
self.prev_handlers[signum] = prev_handler
|
self.prev_handlers[signum] = prev_handler
|
||||||
signal.signal(signum, self._signal_handler)
|
signal.signal(signum, self._signal_handler)
|
||||||
|
|
||||||
def reset_signal_handlers(self):
|
def _reset_signal_handlers(self):
|
||||||
"""Resets signal handlers for signals in _SIGNALS."""
|
"""Resets signal handlers for signals in _SIGNALS."""
|
||||||
for signum in self.prev_handlers:
|
for signum in self.prev_handlers:
|
||||||
signal.signal(signum, self.prev_handlers[signum])
|
signal.signal(signum, self.prev_handlers[signum])
|
||||||
self.prev_handlers.clear()
|
self.prev_handlers.clear()
|
||||||
|
|
||||||
def _signal_handler(self, signum, unused_frame):
|
def _signal_handler(self, signum, unused_frame):
|
||||||
"""Calls registered functions and the previous signal handler.
|
"""Replacement function for handling recieved signals.
|
||||||
|
|
||||||
|
Store the recieved signal. If we are executing the code block in
|
||||||
|
the body of the context manager, stop by raising signal exit.
|
||||||
|
|
||||||
:param int signum: number of current signal
|
:param int signum: number of current signal
|
||||||
|
|
||||||
"""
|
"""
|
||||||
logger.debug("Singal %s encountered", signum)
|
self.received_signals.append(signum)
|
||||||
self.call_registered()
|
if not self.body_executed:
|
||||||
signal.signal(signum, self.prev_handlers[signum])
|
raise errors.SignalExit
|
||||||
os.kill(os.getpid(), signum)
|
|
||||||
|
def _call_signals(self):
|
||||||
|
"""Finally call the deferred signals."""
|
||||||
|
for signum in self.received_signals:
|
||||||
|
logger.debug("Calling signal %s", signum)
|
||||||
|
os.kill(os.getpid(), signum)
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ class HookCommandNotFound(Error):
|
|||||||
"""Failed to find a hook command in the PATH."""
|
"""Failed to find a hook command in the PATH."""
|
||||||
|
|
||||||
|
|
||||||
|
class SignalExit(Error):
|
||||||
|
"""A Unix signal was recieved while in the ErrorHandler context manager."""
|
||||||
|
|
||||||
|
|
||||||
# Auth Handler Errors
|
# Auth Handler Errors
|
||||||
class AuthorizationError(Error):
|
class AuthorizationError(Error):
|
||||||
"""Authorization error."""
|
"""Authorization error."""
|
||||||
|
|||||||
@@ -1020,6 +1020,12 @@ class CLITest(unittest.TestCase): # pylint: disable=too-many-public-methods
|
|||||||
args = ['renew', '--dialog', '--text']
|
args = ['renew', '--dialog', '--text']
|
||||||
self.assertRaises(errors.Error, self._call, args)
|
self.assertRaises(errors.Error, self._call, args)
|
||||||
|
|
||||||
|
def test_text_mode_when_verbose(self):
|
||||||
|
parse = self._get_argument_parser()
|
||||||
|
short_args = ['-v']
|
||||||
|
namespace = parse(short_args)
|
||||||
|
self.assertTrue(namespace.text_mode)
|
||||||
|
|
||||||
|
|
||||||
class DetermineAccountTest(unittest.TestCase):
|
class DetermineAccountTest(unittest.TestCase):
|
||||||
"""Tests for certbot.cli._determine_account."""
|
"""Tests for certbot.cli._determine_account."""
|
||||||
|
|||||||
@@ -1,10 +1,38 @@
|
|||||||
"""Tests for certbot.error_handler."""
|
"""Tests for certbot.error_handler."""
|
||||||
|
import contextlib
|
||||||
|
import os
|
||||||
import signal
|
import signal
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
|
def get_signals(signums):
|
||||||
|
"""Get the handlers for an iterable of signums."""
|
||||||
|
return dict((s, signal.getsignal(s)) for s in signums)
|
||||||
|
|
||||||
|
|
||||||
|
def set_signals(sig_handler_dict):
|
||||||
|
"""Set the signal (keys) with the handler (values) from the input dict."""
|
||||||
|
for s, h in sig_handler_dict.items():
|
||||||
|
signal.signal(s, h)
|
||||||
|
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def signal_receiver(signums):
|
||||||
|
"""Context manager to catch signals"""
|
||||||
|
signals = []
|
||||||
|
prev_handlers = {}
|
||||||
|
prev_handlers = get_signals(signums)
|
||||||
|
set_signals(dict((s, lambda s, _: signals.append(s)) for s in signums))
|
||||||
|
yield signals
|
||||||
|
set_signals(prev_handlers)
|
||||||
|
|
||||||
|
|
||||||
|
def send_signal(signum):
|
||||||
|
"""Send the given signal"""
|
||||||
|
os.kill(os.getpid(), signum)
|
||||||
|
|
||||||
|
|
||||||
class ErrorHandlerTest(unittest.TestCase):
|
class ErrorHandlerTest(unittest.TestCase):
|
||||||
"""Tests for certbot.error_handler."""
|
"""Tests for certbot.error_handler."""
|
||||||
@@ -22,6 +50,38 @@ class ErrorHandlerTest(unittest.TestCase):
|
|||||||
self.signals = error_handler._SIGNALS
|
self.signals = error_handler._SIGNALS
|
||||||
|
|
||||||
def test_context_manager(self):
|
def test_context_manager(self):
|
||||||
|
exception_raised = False
|
||||||
|
try:
|
||||||
|
with self.handler:
|
||||||
|
raise ValueError
|
||||||
|
except ValueError:
|
||||||
|
exception_raised = True
|
||||||
|
|
||||||
|
self.assertTrue(exception_raised)
|
||||||
|
self.init_func.assert_called_once_with(*self.init_args,
|
||||||
|
**self.init_kwargs)
|
||||||
|
|
||||||
|
def test_context_manager_with_signal(self):
|
||||||
|
init_signals = get_signals(self.signals)
|
||||||
|
with signal_receiver(self.signals) as signals_received:
|
||||||
|
with self.handler:
|
||||||
|
should_be_42 = 42
|
||||||
|
send_signal(self.signals[0])
|
||||||
|
should_be_42 *= 10
|
||||||
|
|
||||||
|
# check exectuion stoped when the signal was sent
|
||||||
|
self.assertEqual(42, should_be_42)
|
||||||
|
# assert signals were caught
|
||||||
|
self.assertEqual([self.signals[0]], signals_received)
|
||||||
|
# assert the error handling function was just called once
|
||||||
|
self.init_func.assert_called_once_with(*self.init_args,
|
||||||
|
**self.init_kwargs)
|
||||||
|
for signum in self.signals:
|
||||||
|
self.assertEqual(init_signals[signum], signal.getsignal(signum))
|
||||||
|
|
||||||
|
def test_bad_recovery(self):
|
||||||
|
bad_func = mock.MagicMock(side_effect=[ValueError])
|
||||||
|
self.handler.register(bad_func)
|
||||||
try:
|
try:
|
||||||
with self.handler:
|
with self.handler:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
@@ -29,31 +89,17 @@ class ErrorHandlerTest(unittest.TestCase):
|
|||||||
pass
|
pass
|
||||||
self.init_func.assert_called_once_with(*self.init_args,
|
self.init_func.assert_called_once_with(*self.init_args,
|
||||||
**self.init_kwargs)
|
**self.init_kwargs)
|
||||||
|
bad_func.assert_called_once_with()
|
||||||
|
|
||||||
@mock.patch('certbot.error_handler.os')
|
def test_bad_recovery_with_signal(self):
|
||||||
@mock.patch('certbot.error_handler.signal')
|
sig1 = self.signals[0]
|
||||||
def test_signal_handler(self, mock_signal, mock_os):
|
sig2 = self.signals[-1]
|
||||||
# pylint: disable=protected-access
|
bad_func = mock.MagicMock(side_effect=lambda: send_signal(sig1))
|
||||||
mock_signal.getsignal.return_value = signal.SIG_DFL
|
|
||||||
self.handler.set_signal_handlers()
|
|
||||||
signal_handler = self.handler._signal_handler
|
|
||||||
for signum in self.signals:
|
|
||||||
mock_signal.signal.assert_any_call(signum, signal_handler)
|
|
||||||
|
|
||||||
signum = self.signals[0]
|
|
||||||
signal_handler(signum, None)
|
|
||||||
self.init_func.assert_called_once_with(*self.init_args,
|
|
||||||
**self.init_kwargs)
|
|
||||||
mock_os.kill.assert_called_once_with(mock_os.getpid(), signum)
|
|
||||||
|
|
||||||
self.handler.reset_signal_handlers()
|
|
||||||
for signum in self.signals:
|
|
||||||
mock_signal.signal.assert_any_call(signum, signal.SIG_DFL)
|
|
||||||
|
|
||||||
def test_bad_recovery(self):
|
|
||||||
bad_func = mock.MagicMock(side_effect=[ValueError])
|
|
||||||
self.handler.register(bad_func)
|
self.handler.register(bad_func)
|
||||||
self.handler.call_registered()
|
with signal_receiver(self.signals) as signals_received:
|
||||||
|
with self.handler:
|
||||||
|
send_signal(sig2)
|
||||||
|
self.assertEqual([sig2, sig1], signals_received)
|
||||||
self.init_func.assert_called_once_with(*self.init_args,
|
self.init_func.assert_called_once_with(*self.init_args,
|
||||||
**self.init_kwargs)
|
**self.init_kwargs)
|
||||||
bad_func.assert_called_once_with()
|
bad_func.assert_called_once_with()
|
||||||
|
|||||||
+25
-13
@@ -27,14 +27,17 @@ The Apache plugin currently requires a Debian-based OS with augeas version
|
|||||||
Getting Certbot
|
Getting Certbot
|
||||||
===============
|
===============
|
||||||
|
|
||||||
To get specific instructions for installing Certbot on your OS, we recommend
|
To get specific instructions for installing Certbot on your OS,
|
||||||
visiting certbot.eff.org_. If you're offline, you can find some general
|
visit certbot.eff.org_. This is the easiest way to learn how to get
|
||||||
instructions `Quick Installation <install.html>`__
|
Certbot up and running on your system.
|
||||||
|
|
||||||
|
If you're offline, you can find some general
|
||||||
|
instructions under `Quick Installation <install.html>`__.
|
||||||
|
|
||||||
__ installation_
|
__ installation_
|
||||||
.. _certbot.eff.org: https://certbot.eff.org
|
.. _certbot.eff.org: https://certbot.eff.org
|
||||||
|
|
||||||
.. _certbot-auto:
|
.. _certbot-auto: https://certbot.eff.org/docs/using.html#certbot-auto
|
||||||
|
|
||||||
The name of the certbot command
|
The name of the certbot command
|
||||||
-------------------------------
|
-------------------------------
|
||||||
@@ -413,7 +416,12 @@ Running with Docker
|
|||||||
Docker_ is an amazingly simple and quick way to obtain a
|
Docker_ is an amazingly simple and quick way to obtain a
|
||||||
certificate. However, this mode of operation is unable to install
|
certificate. However, this mode of operation is unable to install
|
||||||
certificates or configure your webserver, because our installer
|
certificates or configure your webserver, because our installer
|
||||||
plugins cannot reach it from inside the Docker container.
|
plugins cannot reach your webserver from inside the Docker container.
|
||||||
|
|
||||||
|
Most users should use the operating system packages (see instructions at
|
||||||
|
certbot.eff.org_) or, as a fallback, ``certbot-auto``. You should only
|
||||||
|
use Docker if you are sure you know what you are doing and have a
|
||||||
|
good reason to do so.
|
||||||
|
|
||||||
You should definitely read the :ref:`where-certs` section, in order to
|
You should definitely read the :ref:`where-certs` section, in order to
|
||||||
know how to manage the certs
|
know how to manage the certs
|
||||||
@@ -432,11 +440,15 @@ to, `install Docker`_, then issue the following command:
|
|||||||
sudo docker run -it --rm -p 443:443 -p 80:80 --name certbot \
|
sudo docker run -it --rm -p 443:443 -p 80:80 --name certbot \
|
||||||
-v "/etc/letsencrypt:/etc/letsencrypt" \
|
-v "/etc/letsencrypt:/etc/letsencrypt" \
|
||||||
-v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
|
-v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
|
||||||
quay.io/letsencrypt/letsencrypt:latest auth
|
quay.io/letsencrypt/letsencrypt:latest certonly
|
||||||
|
|
||||||
and follow the instructions (note that ``auth`` command is explicitly
|
Running Certbot with the ``certonly`` command will obtain a certificate and place it in the directory
|
||||||
used - no installer plugins involved). Your new cert will be available
|
``/etc/letsencrypt/live`` on your system. Because Certonly cannot install the certificate from
|
||||||
in ``/etc/letsencrypt/live`` on the host.
|
within Docker, you must install the certificate manually according to the procedure
|
||||||
|
recommended by the provider of your webserver.
|
||||||
|
|
||||||
|
For more information about the layout
|
||||||
|
of the ``/etc/letsencrypt`` directory, see :ref:`where-certs`.
|
||||||
|
|
||||||
.. _Docker: https://docker.com
|
.. _Docker: https://docker.com
|
||||||
.. _`install Docker`: https://docs.docker.com/userguide/
|
.. _`install Docker`: https://docs.docker.com/userguide/
|
||||||
@@ -562,10 +574,10 @@ whole process is described in the :doc:`contributing`.
|
|||||||
Comparison of different methods
|
Comparison of different methods
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
Unless you have a very specific requirements, we kindly suggest that you use
|
Unless you have very specific requirements, we kindly suggest that you use
|
||||||
the certbot-auto_ method. It's the fastest, the most thoroughly
|
the Certbot packages provided by your package manager (see certbot.eff.org_).
|
||||||
tested and the most reliable way of getting our software and the free
|
If such packages are not available, we recommend using ``certbot-auto``, which
|
||||||
TLS/SSL certificates!
|
automates the process of installing Certbot on your system.
|
||||||
|
|
||||||
Beyond the methods discussed here, other methods may be possible, such as
|
Beyond the methods discussed here, other methods may be possible, such as
|
||||||
installing Certbot directly with pip from PyPI or downloading a ZIP
|
installing Certbot directly with pip from PyPI or downloading a ZIP
|
||||||
|
|||||||
@@ -918,13 +918,19 @@ UNLIKELY_EOF
|
|||||||
# Set PATH so pipstrap upgrades the right (v)env:
|
# Set PATH so pipstrap upgrades the right (v)env:
|
||||||
PATH="$VENV_BIN:$PATH" "$VENV_BIN/python" "$TEMP_DIR/pipstrap.py"
|
PATH="$VENV_BIN:$PATH" "$VENV_BIN/python" "$TEMP_DIR/pipstrap.py"
|
||||||
set +e
|
set +e
|
||||||
PIP_OUT=`"$VENV_BIN/pip" install --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" 2>&1`
|
if [ "$VERBOSE" = 1 ]; then
|
||||||
|
"$VENV_BIN/pip" install --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt"
|
||||||
|
else
|
||||||
|
PIP_OUT=`"$VENV_BIN/pip" install --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" 2>&1`
|
||||||
|
fi
|
||||||
PIP_STATUS=$?
|
PIP_STATUS=$?
|
||||||
set -e
|
set -e
|
||||||
if [ "$PIP_STATUS" != 0 ]; then
|
if [ "$PIP_STATUS" != 0 ]; then
|
||||||
# Report error. (Otherwise, be quiet.)
|
# Report error. (Otherwise, be quiet.)
|
||||||
echo "Had a problem while installing Python packages:"
|
echo "Had a problem while installing Python packages."
|
||||||
echo "$PIP_OUT"
|
if [ "$VERBOSE" != 1 ]; then
|
||||||
|
echo "$PIP_OUT"
|
||||||
|
fi
|
||||||
rm -rf "$VENV_PATH"
|
rm -rf "$VENV_PATH"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -253,13 +253,19 @@ UNLIKELY_EOF
|
|||||||
# Set PATH so pipstrap upgrades the right (v)env:
|
# Set PATH so pipstrap upgrades the right (v)env:
|
||||||
PATH="$VENV_BIN:$PATH" "$VENV_BIN/python" "$TEMP_DIR/pipstrap.py"
|
PATH="$VENV_BIN:$PATH" "$VENV_BIN/python" "$TEMP_DIR/pipstrap.py"
|
||||||
set +e
|
set +e
|
||||||
PIP_OUT=`"$VENV_BIN/pip" install --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" 2>&1`
|
if [ "$VERBOSE" = 1 ]; then
|
||||||
|
"$VENV_BIN/pip" install --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt"
|
||||||
|
else
|
||||||
|
PIP_OUT=`"$VENV_BIN/pip" install --no-cache-dir --require-hashes -r "$TEMP_DIR/letsencrypt-auto-requirements.txt" 2>&1`
|
||||||
|
fi
|
||||||
PIP_STATUS=$?
|
PIP_STATUS=$?
|
||||||
set -e
|
set -e
|
||||||
if [ "$PIP_STATUS" != 0 ]; then
|
if [ "$PIP_STATUS" != 0 ]; then
|
||||||
# Report error. (Otherwise, be quiet.)
|
# Report error. (Otherwise, be quiet.)
|
||||||
echo "Had a problem while installing Python packages:"
|
echo "Had a problem while installing Python packages."
|
||||||
echo "$PIP_OUT"
|
if [ "$VERBOSE" != 1 ]; then
|
||||||
|
echo "$PIP_OUT"
|
||||||
|
fi
|
||||||
rm -rf "$VENV_PATH"
|
rm -rf "$VENV_PATH"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user