Error en renovación de certificado

Por favor, complete los campos del siguiente formulario para que podamos ayudarle de la mejor forma posible. Nota: debe proporcionar su nombre de dominio para obtener ayuda. Los nombres de dominio de los certificados emitidos se hacen públicos en los registros de Transparencia de Certificados (por ejemplo, crt.sh | example.com), por lo que esconder aquí su nombre de dominio no sirve de nada, únicamente nos dificulta prestarle la ayuda solicitada.

Puedo leer las respuestas en Inglés (sí o no): Si

Mi dominio es: motokits.com.co

Ejecuté este comando:
No se realizó la renovación automática programada.
En diciembre configuré modsecurity.
El sitio aparece como inseguro.
Ejecuté $sudo certbot renew --dry_run y me respondió:

Produjo esta salida:


Cert is due for renewal, auto-renewing...
Could not choose appropriate plugin: The apache plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('There has been an error in parsing the file /etc/mod security/modsecurity.conf on line 67: Syntax error',)
Attempting to renew cert (motokits.com.co) from /etc/letsencrypt/renewal/motokit s.com.co.conf produced an unexpected error: The apache plugin is not working; th ere may be problems with your existing configuration.
The error was: PluginError('There has been an error in parsing the file /etc/mod security/modsecurity.conf on line 67: Syntax error',). Skipping.
All renewal attempts failed. The following certs could not be renewed:
/etc/letsencrypt/live/dominio.com.co/fullchain.pem (failure)


** DRY RUN: simulating 'certbot renew' close to cert expiry
** (The test certificates below have not been saved.)

Mi servidor web es (incluya la versión):
apache 2.4.29
El sistema operativo en el que se ejecuta mi servidor web es (incluya la versión):
Ubuntu 18.04
Mi proveedor de alojamiento web (si aplica) es:
DigitalOcean
Puedo iniciar una sesión en una shell root en mi servidor (sí, no o no lo sé):
si
Estoy usando un panel de control para administrar mi sitio (no o proporcione el nombre y la versión del panel de control):
No
La versión de mi cliente es (por ejemplo, si usa certbot, muestre la salida de certbot --version o certbot-auto --version): cerbot 0.31.0

2 Likes

Hola @Jairos2021,

Could you please post the contents of /etc/modsecurity/modsecurity.conf? It sounds like you have a problem in that file, and we will need to fix it to proceed.

1 Like

This is my modsecurity.con file. Thank you.

# -- Rule engine initialization ----------------------------------------------

# Enable ModSecurity, attaching it to every transaction. Use detection
# only to start with, because that minimises the chances of post-installation
# disruption.
#
SecRuleEngine DetectionOnly


# -- Request body handling ---------------------------------------------------

# Allow ModSecurity to access request bodies. If you don't, ModSecurity
# won't be able to see any POST parameters, which opens a large security
# hole for attackers to exploit.
#
SecRequestBodyAccess On


# Enable XML request body parser.
# Initiate XML Processor in case of xml content-type
#
SecRule REQUEST_HEADERS:Content-Type "(?:application(?:/soap\+|/)|text/)xml" \
     "id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML"

# Enable JSON request body parser.
# Initiate JSON Processor in case of JSON content-type; change accordingly
# if your application does not use 'application/json'
#
SecRule REQUEST_HEADERS:Content-Type "application/json" \
     "id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"

# Maximum request body size we will accept for buffering. If you support
# file uploads then the value given on the first line has to be as large
# as the largest file you are willing to accept. The second value refers
# to the size of data, with files excluded. You want to keep that value as
# low as practical.
#
SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072

# Store up to 128 KB of request body data in memory. When the multipart
# parser reachers this limit, it will start using your hard disk for
# storage. That is slow, but unavoidable.
#
SecRequestBodyInMemoryLimit 131072

# What do do if the request body size is above our configured limit.
# Keep in mind that this setting will automatically be set to ProcessPartial
# when SecRuleEngine is set to DetectionOnly mode in order to minimize
# disruptions when initially deploying ModSecurity.
#
SecRequestBodyLimitAction Reject

# Verify that we've correctly processed the request body.
# As a rule of thumb, when failing to process a request body
# you should reject the request (when deployed in blocking mode)
# or log a high-severity alert (when deployed in detection-only mode).
#
SecRule REQBODY_ERROR "!@eq 0" \
"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2"

# By default be strict with what we accept in the multipart/form-data
# request body. If the rule below proves to be too strict for your
# environment consider changing it to detection-only. You are encouraged
# _not_ to remove it altogether.
#
SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
"id:'200003',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed strict validation: \
PE %{REQBODY_PROCESSOR_ERROR}, \
BQ %{MULTIPART_BOUNDARY_QUOTED}, \
BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
DB %{MULTIPART_DATA_BEFORE}, \
DA %{MULTIPART_DATA_AFTER}, \
HF %{MULTIPART_HEADER_FOLDING}, \
LF %{MULTIPART_LF_LINE}, \
SM %{MULTIPART_MISSING_SEMICOLON}, \
IQ %{MULTIPART_INVALID_QUOTING}, \
IP %{MULTIPART_INVALID_PART}, \
IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'"

# Did we see anything that might be a boundary?
#
SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" \
"id:'200004',phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'"

# PCRE Tuning
# We want to avoid a potential RegEx DoS condition
#
SecPcreMatchLimit 100000
SecPcreMatchLimitRecursion 100000

# Some internal errors will set flags in TX and we will need to look for these.
# All of these are prefixed with "MSC_".  The following flags currently exist:
#
# MSC_PCRE_LIMITS_EXCEEDED: PCRE match limits were exceeded.
#
SecRule TX:/^MSC_/ "!@streq 0" \
        "id:'200005',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"


# -- Response body handling --------------------------------------------------

# Allow ModSecurity to access response bodies. 
# You should have this directive enabled in order to identify errors
# and data leakage issues.
# 
# Do keep in mind that enabling this directive does increases both
# memory consumption and response latency.
#
SecResponseBodyAccess On

# Which response MIME types do you want to inspect? You should adjust the
# configuration below to catch documents but avoid static files
# (e.g., images and archives).
#
SecResponseBodyMimeType text/plain text/html text/xml

# Buffer response bodies of up to 512 KB in length.
SecResponseBodyLimit 524288

# What happens when we encounter a response body larger than the configured
# limit? By default, we process what we have and let the rest through.
# That's somewhat less secure, but does not break any legitimate pages.
#
SecResponseBodyLimitAction ProcessPartial


# -- Filesystem configuration ------------------------------------------------

# The location where ModSecurity stores temporary files (for example, when
# it needs to handle a file upload that is larger than the configured limit).
# 
# This default setting is chosen due to all systems have /tmp available however, 
# this is less than ideal. It is recommended that you specify a location that's private.
#
SecTmpDir /tmp/

# The location where ModSecurity will keep its persistent data.  This default setting 
# is chosen due to all systems have /tmp available however, it
# too should be updated to a place that other users can't access.
#
SecDataDir /tmp/


# -- File uploads handling configuration -------------------------------------

# The location where ModSecurity stores intercepted uploaded files. This
# location must be private to ModSecurity. You don't want other users on
# the server to access the files, do you?
#
#SecUploadDir /opt/modsecurity/var/upload/

# By default, only keep the files that were determined to be unusual
# in some way (by an external inspection script). For this to work you
# will also need at least one file inspection rule.
#
#SecUploadKeepFiles RelevantOnly

# Uploaded files are by default created with permissions that do not allow
# any other user to access them. You may need to relax that if you want to
# interface ModSecurity to an external program (e.g., an anti-virus).
#
#SecUploadFileMode 0600


# -- Debug log configuration -------------------------------------------------

# The default debug log configuration is to duplicate the error, warning
# and notice messages from the error log.
#
#SecDebugLog /opt/modsecurity/var/log/debug.log
#SecDebugLogLevel 3


# -- Audit log configuration -------------------------------------------------

# Log the transactions that are marked by a rule, as well as those that
# trigger a server error (determined by a 5xx or 4xx, excluding 404,  
# level response status codes).
#
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"

# Log everything we know about a transaction.
SecAuditLogParts ABDEFHIJZ

# Use a single file for logging. This is much easier to look at, but
# assumes that you will use the audit log only ocassionally.
#
SecAuditLogType Serial
SecAuditLog /var/log/apache2/modsec_audit.log

# Specify the path for concurrent audit logging.
#SecAuditLogStorageDir /opt/modsecurity/var/audit/


# -- Miscellaneous -----------------------------------------------------------

# Use the most commonly used application/x-www-form-urlencoded parameter
# separator. There's probably only one application somewhere that uses
# something else so don't expect to change this value.
#
SecArgumentSeparator &

# Settle on version 0 (zero) cookies, as that is what most applications
# use. Using an incorrect cookie version may open your installation to
# evasion attacks (against the rules that examine named cookies).
#
SecCookieFormat 0

# Specify your Unicode Code Point.
# This mapping is used by the t:urlDecodeUni transformation function
# to properly map encoded data to your language. Properly setting
# these directives helps to reduce false positives and negatives.
#
SecUnicodeMapFile unicode.mapping 20127

# Improve the quality of ModSecurity by sharing information about your
# current ModSecurity version and dependencies versions.
# The following information will be shared: ModSecurity version,
# Web Server version, APR version, PCRE version, Lua version, Libxml2
# version, Anonymous unique id for host.
SecStatusEngine On
1 Like

Great. Around line 67 we see this:

SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
"id:'200003',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed strict validation: \
PE %{REQBODY_PROCESSOR_ERROR}, \
BQ %{MULTIPART_BOUNDARY_QUOTED}, \
BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
DB %{MULTIPART_DATA_BEFORE}, \
DA %{MULTIPART_DATA_AFTER}, \
HF %{MULTIPART_HEADER_FOLDING}, \
LF %{MULTIPART_LF_LINE}, \
SM %{MULTIPART_MISSING_SEMICOLON}, \
IQ %{MULTIPART_INVALID_QUOTING}, \
IP %{MULTIPART_INVALID_PART}, \
IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'"

Certbot has its own internal parser for Apache configs, which is slightly different than Apache's parser. It might be having trouble with the \ at the end of each line here. @schoen is that plausible?

@jairos2021: One thing you could try: At each place in this file where you see \ at the end of the line, join it with the next line and remove the \. E.g.:

SecRule MULTIPART_STRICT_ERROR "!@eq 0" "id:'200003',phase:2,t:none,log,deny,status:400, msg:'Multipart request body failed strict validation: ...

Did you newly install modsecurity since the last time you renewed a certificate?

1 Like

Yes, I'm also thinking about the combination of the " with the \ and newlines... that is, all of this is supposed to be a single string (!).

1 Like

first, install cerbot (may 2020), december 2020 install modsecurity.
the browser gives me certificate error in March 2021.
Then, manually running certbot gives an error in modsecurity.conf

Now, change /

1 Like

Edit Line 69 modsecurity.conf
Only one line
SecRule MULTIPART_STRICT_ERROR "!@eq 0" "id:'200003',phase:2,t:none,log,deny,status:400, msg:'Multipart request body failed strict validation: PE %{REQBODY_PROCESSOR_ERROR}, BQ %{MULTIPART_BOUNDARY_QUOTED}, BW %{MULTIPART_BOUNDARY_WHITESPACE}, DB %{MULTIPART_DATA_BEFORE}, DA %{MULTIPART_DATA_AFTER}, HF %{MULTIPART_HEADER_FOLDING}, LF %{MULTIPART_LF_LINE}, SM %{MULTIPART_MISSING_SEMICOLON}, IQ %{MULTIPART_INVALID_QUOTING}, IP %{MULTIPART_INVALID_PART}, IH %{MULTIPART_INVALID_HEADER_FOLDING}, FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'"

Run
$sudo apachectl -S
Ok.

Run
sudo certbot --apache -d motokits.com.co -d www.motokits.com.co -d mail.motokits.com.co -d correo.motokits.com.co
Saving debug log to /var/log/letsencrypt/letsencrypt.log
The apache plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('There has been an error in parsing the file /usr/share/modsecurity-crs/crs-setup.conf on line 176: Syntax error')

file /usr/share/modsecurity-crs/crs-setup.conf on line 176 are comments lines.

2 Likes

This is my crs-setup.conf:

# ------------------------------------------------------------------------
# OWASP ModSecurity Core Rule Set ver.3.2.0
# Copyright (c) 2006-2019 Trustwave and contributors. All rights reserved.
#
# The OWASP ModSecurity Core Rule Set is distributed under
# Apache Software License (ASL) version 2
# Please see the enclosed LICENSE file for full details.
# ------------------------------------------------------------------------


#
# -- [[ Introduction ]] --------------------------------------------------------
#
# The OWASP ModSecurity Core Rule Set (CRS) is a set of generic attack
# detection rules that provide a base level of protection for any web
# application. They are written for the open source, cross-platform
# ModSecurity Web Application Firewall.
#
# See also:
# https://coreruleset.org/
# https://github.com/SpiderLabs/owasp-modsecurity-crs
# https://www.owasp.org/index.php/Category:OWASP_ModSecurity_Core_Rule_Set_Project
#


#
# -- [[ System Requirements ]] -------------------------------------------------
#
# CRS requires ModSecurity version 2.8.0 or above.
# We recommend to always use the newest ModSecurity version.
#
# The configuration directives/settings in this file are used to control
# the OWASP ModSecurity CRS. These settings do **NOT** configure the main
# ModSecurity settings (modsecurity.conf) such as SecRuleEngine,
# SecRequestBodyAccess, SecAuditEngine, SecDebugLog, and XML processing.
#
# The CRS assumes that modsecurity.conf has been loaded. It is bundled with
# ModSecurity. If you don't have it, you can get it from:
# 2.x: https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v2/master/modsecurity.conf-recommended
# 3.x: https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended
#
# The order of file inclusion in your webserver configuration should always be:
# 1. modsecurity.conf
# 2. crs-setup.conf (this file)
# 3. rules/*.conf (the CRS rule files)
#
# Please refer to the INSTALL file for detailed installation instructions.
#


#
# -- [[ Mode of Operation: Anomaly Scoring vs. Self-Contained ]] ---------------
#
# The CRS can run in two modes:
#
# -- [[ Anomaly Scoring Mode (default) ]] --
# In CRS3, anomaly mode is the default and recommended mode, since it gives the
# most accurate log information and offers the most flexibility in setting your
# blocking policies. It is also called "collaborative detection mode".
# In this mode, each matching rule increases an 'anomaly score'.
# At the conclusion of the inbound rules, and again at the conclusion of the
# outbound rules, the anomaly score is checked, and the blocking evaluation
# rules apply a disruptive action, by default returning an error 403.
#
# -- [[ Self-Contained Mode ]] --
# In this mode, rules apply an action instantly. This was the CRS2 default.
# It can lower resource usage, at the cost of less flexibility in blocking policy
# and less informative audit logs (only the first detected threat is logged).
# Rules inherit the disruptive action that you specify (i.e. deny, drop, etc).
# The first rule that matches will execute this action. In most cases this will
# cause evaluation to stop after the first rule has matched, similar to how many
# IDSs function.
#
# -- [[ Alert Logging Control ]] --
# In the mode configuration, you must also adjust the desired logging options.
# There are three common options for dealing with logging. By default CRS enables
# logging to the webserver error log (or Event viewer) plus detailed logging to
# the ModSecurity audit log (configured under SecAuditLog in modsecurity.conf).
#
# - To log to both error log and ModSecurity audit log file, use: "log,auditlog"
# - To log *only* to the ModSecurity audit log file, use: "nolog,auditlog"
# - To log *only* to the error log file, use: "log,noauditlog"
#
# Examples for the various modes follow.
# You must leave one of the following options enabled.
# Note that you must specify the same line for phase:1 and phase:2.
#

# Default: Anomaly Scoring mode, log to error log, log to ModSecurity audit log
# - By default, offending requests are blocked with an error 403 response.
# - To change the disruptive action, see RESPONSE-999-EXCEPTIONS.conf.example
#   and review section 'Changing the Disruptive Action for Anomaly Mode'.
# - In Apache, you can use ErrorDocument to show a friendly error page or
#   perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html
#
SecDefaultAction "phase:1,log,auditlog,pass"
SecDefaultAction "phase:2,log,auditlog,pass"

# Example: Anomaly Scoring mode, log only to ModSecurity audit log
# - By default, offending requests are blocked with an error 403 response.
# - To change the disruptive action, see RESPONSE-999-EXCEPTIONS.conf.example
#   and review section 'Changing the Disruptive Action for Anomaly Mode'.
# - In Apache, you can use ErrorDocument to show a friendly error page or
#   perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html
#
# SecDefaultAction "phase:1,nolog,auditlog,pass"
# SecDefaultAction "phase:2,nolog,auditlog,pass"

# Example: Self-contained mode, return error 403 on blocking
# - In this configuration the default disruptive action becomes 'deny'. After a
#   rule triggers, it will stop processing the request and return an error 403.
# - You can also use a different error status, such as 404, 406, et cetera.
# - In Apache, you can use ErrorDocument to show a friendly error page or
#   perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html
#
# SecDefaultAction "phase:1,log,auditlog,deny,status:403"
# SecDefaultAction "phase:2,log,auditlog,deny,status:403"

# Example: Self-contained mode, redirect back to homepage on blocking
# - In this configuration the 'tag' action includes the Host header data in the
#   log. This helps to identify which virtual host triggered the rule (if any).
# - Note that this might cause redirect loops in some situations; for example
#   if a Cookie or User-Agent header is blocked, it will also be blocked when
#   the client subsequently tries to access the homepage. You can also redirect
#   to another custom URL.
# SecDefaultAction "phase:1,log,auditlog,redirect:'http://%{request_headers.host}/',tag:'Host: %{request_headers.host}'"
# SecDefaultAction "phase:2,log,auditlog,redirect:'http://%{request_headers.host}/',tag:'Host: %{request_headers.host}'"


#
# -- [[ Paranoia Level Initialization ]] ---------------------------------------
#
# The Paranoia Level (PL) setting allows you to choose the desired level
# of rule checks that will add to your anomaly scores.
#
# With each paranoia level increase, the CRS enables additional rules
# giving you a higher level of security. However, higher paranoia levels
# also increase the possibility of blocking some legitimate traffic due to
# false alarms (also named false positives or FPs). If you use higher
# paranoia levels, it is likely that you will need to add some exclusion
# rules for certain requests and applications receiving complex input.
#
# - A paranoia level of 1 is default. In this level, most core rules
#   are enabled. PL1 is advised for beginners, installations
#   covering many different sites and applications, and for setups
#   with standard security requirements.
#   At PL1 you should face FPs rarely. If you encounter FPs, please
#   open an issue on the CRS GitHub site and don't forget to attach your
#   complete Audit Log record for the request with the issue.
# - Paranoia level 2 includes many extra rules, for instance enabling
#   many regexp-based SQL and XSS injection protections, and adding
#   extra keywords checked for code injections. PL2 is advised
#   for moderate to experienced users desiring more complete coverage
#   and for installations with elevated security requirements.
#   PL2 comes with some FPs which you need to handle.
# - Paranoia level 3 enables more rules and keyword lists, and tweaks
#   limits on special characters used. PL3 is aimed at users experienced
#   at the handling of FPs and at installations with a high security
#   requirement.
# - Paranoia level 4 further restricts special characters.
#   The highest level is advised for experienced users protecting
#   installations with very high security requirements. Running PL4 will
#   likely produce a very high number of FPs which have to be
#   treated before the site can go productive.
#
# All rules will log their PL to the audit log;
# example: [tag "paranoia-level/2"]. This allows you to deduct from the
# audit log how the WAF behavior is affected by paranoia level.
#
# It is important to also look into the variable
# tx.enforce_bodyproc_urlencoded (Enforce Body Processor URLENCODED)
# defined below. Enabling it closes a possible bypass of CRS.
#
# Uncomment this rule to change the default:
#
#SecAction \
#  "id:900000,\
#   phase:1,\
#   nolog,\
#   pass,\
#   t:none,\
#   setvar:tx.paranoia_level=1"


# It is possible to execute rules from a higher paranoia level but not include
# them in the anomaly scoring. This allows you to take a well-tuned system on
# paranoia level 1 and add rules from paranoia level 2 without having to fear
# the new rules would lead to false positives that raise your score above the
# threshold.
# This optional feature is enabled by uncommenting the following rule and
# setting the tx.executing_paranoia_level.
# Technically, rules up to the level defined in tx.executing_paranoia_level
# will be executed, but only the rules up to tx.paranoia_level affect the
# anomaly scores.
# By default, tx.executing_paranoia_level is set to tx.paranoia_level.
# tx.executing_paranoia_level must not be lower than tx.paranoia_level.
#
# Please notice that setting tx.executing_paranoia_level to a higher paranoia
# level results in a performance impact that is equally high as setting
# tx.paranoia_level to said level.
#
#SecAction \
#  "id:900001,\
#   phase:1,\
#   nolog,\
#   pass,\
#   t:none,\
#   setvar:tx.executing_paranoia_level=1"


#
# -- [[ Enforce Body Processor URLENCODED ]] -----------------------------------
#
# ModSecurity selects the body processor based on the Content-Type request
# header. But clients are not always setting the Content-Type header for their
# request body payloads. This will leave ModSecurity with limited vision into
# the payload.  The variable tx.enforce_bodyproc_urlencoded lets you force the
# URLENCODED body processor in these situations. This is off by default, as it
# implies a change of the behaviour of ModSecurity beyond CRS (the body
# processor applies to all rules, not only CRS) and because it may lead to
# false positives already on paranoia level 1. However, enabling this variable
# closes a possible bypass of CRS so it should be considered.
#
# Uncomment this rule to change the default:
#
#SecAction \
#  "id:900010,\
#   phase:1,\
#   nolog,\
#   pass,\
#   t:none,\
#   setvar:tx.enforce_bodyproc_urlencoded=1"


#
# -- [[ Anomaly Mode Severity Levels ]] ----------------------------------------
#
# Each rule in the CRS has an associated severity level.
# These are the default scoring points for each severity level.
# These settings will be used to increment the anomaly score if a rule matches.
# You may adjust these points to your liking, but this is usually not needed.
#
# - CRITICAL severity: Anomaly Score of 5.
#       Mostly generated by the application attack rules (93x and 94x files).
# - ERROR severity: Anomaly Score of 4.
#       Generated mostly from outbound leakage rules (95x files).
# - WARNING severity: Anomaly Score of 3.
#       Generated mostly by malicious client rules (91x files).
# - NOTICE severity: Anomaly Score of 2.
#       Generated mostly by the protocol rules (92x files).
#
# In anomaly mode, these scores are cumulative.
# So it's possible for a request to hit multiple rules.
#
# (Note: In this file, we use 'phase:1' to set CRS configuration variables.
# In general, 'phase:request' is used. However, we want to make absolutely sure
# that all configuration variables are set before the CRS rules are processed.)
#
#SecAction \
# "id:900100,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:tx.critical_anomaly_score=5,\
#  setvar:tx.error_anomaly_score=4,\
#  setvar:tx.warning_anomaly_score=3,\
#  setvar:tx.notice_anomaly_score=2"


#
# -- [[ Anomaly Mode Blocking Threshold Levels ]] ------------------------------
#
# Here, you can specify at which cumulative anomaly score an inbound request,
# or outbound response, gets blocked.
#
# Most detected inbound threats will give a critical score of 5.
# Smaller violations, like violations of protocol/standards, carry lower scores.
#
# [ At default value ]
# If you keep the blocking thresholds at the defaults, the CRS will work
# similarly to previous CRS versions: a single critical rule match will cause
# the request to be blocked and logged.
#
# [ Using higher values ]
# If you want to make the CRS less sensitive, you can increase the blocking
# thresholds, for instance to 7 (which would require multiple rule matches
# before blocking) or 10 (which would require at least two critical alerts - or
# a combination of many lesser alerts), or even higher. However, increasing the
# thresholds might cause some attacks to bypass the CRS rules or your policies.
#
# [ New deployment strategy: Starting high and decreasing ]
# It is a common practice to start a fresh CRS installation with elevated
# anomaly scoring thresholds (>100) and then lower the limits as your
# confidence in the setup grows. You may also look into the Sampling
# Percentage section below for a different strategy to ease into a new
# CRS installation.
#
# [ Anomaly Threshold / Paranoia Level Quadrant ]
#
#     High Anomaly Limit   |   High Anomaly Limit
#     Low Paranoia Level   |   High Paranoia Level
#     -> Fresh Site        |   -> Experimental Site
# ------------------------------------------------------
#     Low Anomaly Limit    |   Low Anomaly Limit
#     Low Paranoia Level   |   High Paranoia Level
#     -> Standard Site     |   -> High Security Site
#
# Uncomment this rule to change the defaults:
#
#SecAction \
# "id:900110,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:tx.inbound_anomaly_score_threshold=5,\
#  setvar:tx.outbound_anomaly_score_threshold=4"

#
# -- [[ Application Specific Rule Exclusions ]] ----------------------------------------
#
# Some well-known applications may undertake actions that appear to be
# malicious. This includes actions such as allowing HTML or Javascript within
# parameters. In such cases the CRS aims to prevent false positives by allowing
# administrators to enable prebuilt, application specific exclusions on an
# application by application basis.
# These application specific exclusions are distinct from the rules that would
# be placed in the REQUEST-900-EXCLUSION-RULES-BEFORE-CRS configuration file as
# they are prebuilt for specific applications. The 'REQUEST-900' file is
# designed for users to add their own custom exclusions. Note, using these
# application specific exclusions may loosen restrictions of the CRS,
# especially if used with an application they weren't designed for. As a result
# they should be applied with care.
# To use this functionality you must specify a supported application. To do so
# uncomment rule 900130. In addition to uncommenting the rule you will need to
# specify which application(s) you'd like to enable exclusions for. Only a
# (very) limited set of applications are currently supported, please use the
# filenames prefixed with 'REQUEST-903' to guide you in your selection.
# Such filenames use the following convention:
# REQUEST-903.9XXX-{APPNAME}-EXCLUSIONS-RULES.conf
#
# It is recommended if you run multiple web applications on your site to limit
# the effects of the exclusion to only the path where the excluded webapp
# resides using a rule similar to the following example:
# SecRule REQUEST_URI "@beginsWith /wordpress/" setvar:tx.crs_exclusions_wordpress=1

#
# Modify and uncomment this rule to select which application:
#
#SecAction \
# "id:900130,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:tx.crs_exclusions_cpanel=1,\
#  setvar:tx.crs_exclusions_drupal=1,\
#  setvar:tx.crs_exclusions_dokuwiki=1,\
#  setvar:tx.crs_exclusions_nextcloud=1,\
#  setvar:tx.crs_exclusions_wordpress=1,\
#  setvar:tx.crs_exclusions_xenforo=1"

#
# -- [[ HTTP Policy Settings ]] ------------------------------------------------
#
# This section defines your policies for the HTTP protocol, such as:
# - allowed HTTP versions, HTTP methods, allowed request Content-Types
# - forbidden file extensions (e.g. .bak, .sql) and request headers (e.g. Proxy)
#
# These variables are used in the following rule files:
# - REQUEST-911-METHOD-ENFORCEMENT.conf
# - REQUEST-912-DOS-PROTECTION.conf
# - REQUEST-920-PROTOCOL-ENFORCEMENT.conf

# HTTP methods that a client is allowed to use.
# Default: GET HEAD POST OPTIONS
# Example: for RESTful APIs, add the following methods: PUT PATCH DELETE
# Example: for WebDAV, add the following methods: CHECKOUT COPY DELETE LOCK
#          MERGE MKACTIVITY MKCOL MOVE PROPFIND PROPPATCH PUT UNLOCK
# Uncomment this rule to change the default.
#SecAction \
# "id:900200,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'"

# Content-Types that a client is allowed to send in a request.
# Default: |application/x-www-form-urlencoded| |multipart/form-data| |multipart/related|
# |text/xml| |application/xml| |application/soap+xml| |application/x-amf| |application/json|
# |application/octet-stream| |application/csp-report| |application/xss-auditor-report| |text/plain|
# Uncomment this rule to change the default.
#SecAction \
# "id:900220,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:'tx.allowed_request_content_type=|application/x-www-form-urlencoded| |multipart/form-data| |multipart/related| |text/xml| |application/xml| |application/soap+xml| |application/x-amf| |application/json| |application/octet-stream| |application/csp-report| |application/xss-auditor-report| |text/plain|'"

# Allowed HTTP versions.
# Default: HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0
# Example for legacy clients: HTTP/0.9 HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0
# Note that some web server versions use 'HTTP/2', some 'HTTP/2.0', so
# we include both version strings by default.
# Uncomment this rule to change the default.
#SecAction \
# "id:900230,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:'tx.allowed_http_versions=HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0'"

# Forbidden file extensions.
# Guards against unintended exposure of development/configuration files.
# Default: .asa/ .asax/ .ascx/ .axd/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/
# Example: .bak/ .config/ .conf/ .db/ .ini/ .log/ .old/ .pass/ .pdb/ .rdb/ .sql/
# Uncomment this rule to change the default.
#SecAction \
# "id:900240,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:'tx.restricted_extensions=.asa/ .asax/ .ascx/ .axd/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/'"

# Forbidden request headers.
# Header names should be lowercase, enclosed by /slashes/ as delimiters.
# Blocking Proxy header prevents 'httpoxy' vulnerability: https://httpoxy.org
# Default: /proxy/ /lock-token/ /content-range/ /if/
# Uncomment this rule to change the default.
#SecAction \
# "id:900250,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:'tx.restricted_headers=/proxy/ /lock-token/ /content-range/ /if/'"

# File extensions considered static files.
# Extensions include the dot, lowercase, enclosed by /slashes/ as delimiters.
# Used in DoS protection rule. See section "Anti-Automation / DoS Protection".
# Default: /.jpg/ /.jpeg/ /.png/ /.gif/ /.js/ /.css/ /.ico/ /.svg/ /.webp/
# Uncomment this rule to change the default.
#SecAction \
# "id:900260,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:'tx.static_extensions=/.jpg/ /.jpeg/ /.png/ /.gif/ /.js/ /.css/ /.ico/ /.svg/ /.webp/'"

# Content-Types charsets that a client is allowed to send in a request.
# Default: utf-8|iso-8859-1|iso-8859-15|windows-1252
# Uncomment this rule to change the default.
# Use "|" to separate multiple charsets like in the rule defining
# tx.allowed_request_content_type.
#SecAction \
# "id:900280,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:'tx.allowed_request_content_type_charset=utf-8|iso-8859-1|iso-8859-15|windows-1252'"

#
# -- [[ HTTP Argument/Upload Limits ]] -----------------------------------------
#
# Here you can define optional limits on HTTP get/post parameters and uploads.
# This can help to prevent application specific DoS attacks.
#
# These values are checked in REQUEST-920-PROTOCOL-ENFORCEMENT.conf.
# Beware of blocking legitimate traffic when enabling these limits.
#

# Block request if number of arguments is too high
# Default: unlimited
# Example: 255
# Uncomment this rule to set a limit.
#SecAction \
# "id:900300,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:tx.max_num_args=255"

# Block request if the length of any argument name is too high
# Default: unlimited
# Example: 100
# Uncomment this rule to set a limit.
#SecAction \
# "id:900310,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:tx.arg_name_length=100"

# Block request if the length of any argument value is too high
# Default: unlimited
# Example: 400
# Uncomment this rule to set a limit.
#SecAction \
# "id:900320,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:tx.arg_length=400"

# Block request if the total length of all combined arguments is too high
# Default: unlimited
# Example: 64000
# Uncomment this rule to set a limit.
#SecAction \
# "id:900330,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:tx.total_arg_length=64000"

# Block request if the file size of any individual uploaded file is too high
# Default: unlimited
# Example: 1048576
# Uncomment this rule to set a limit.
#SecAction \
# "id:900340,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:tx.max_file_size=1048576"

# Block request if the total size of all combined uploaded files is too high
# Default: unlimited
# Example: 1048576
# Uncomment this rule to set a limit.
#SecAction \
# "id:900350,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:tx.combined_file_sizes=1048576"


#
# -- [[ Easing In / Sampling Percentage ]] -------------------------------------
#
# Adding the Core Rule Set to an existing productive site can lead to false
# positives, unexpected performance issues and other undesired side effects.
#
# It can be beneficial to test the water first by enabling the CRS for a
# limited number of requests only and then, when you have solved the issues (if
# any) and you have confidence in the setup, to raise the ratio of requests
# being sent into the ruleset.
#
# Adjust the percentage of requests that are funnelled into the Core Rules by
# setting TX.sampling_percentage below. The default is 100, meaning that every
# request gets checked by the CRS.  The selection of requests, which are going
# to be checked, is based on a pseudo random number generated by ModSecurity.
#
# If a request is allowed to pass without being checked by the CRS, there is no
# entry in the audit log (for performance reasons), but an error log entry is
# written.  If you want to disable the error log entry, then issue the
# following directive somewhere after the inclusion of the CRS
# (E.g., RESPONSE-999-EXCEPTIONS.conf).
#
# SecRuleUpdateActionById 901150 "nolog"
#
# ATTENTION: If this TX.sampling_percentage is below 100, then some of the
# requests will bypass the Core Rules completely and you lose the ability to
# protect your service with ModSecurity.
#
# Uncomment this rule to enable this feature:
#
#SecAction "id:900400,\
#  phase:1,\
#  pass,\
#  nolog,\
#  setvar:tx.sampling_percentage=100"


#
# -- [[ Project Honey Pot HTTP Blacklist ]] ------------------------------------
#
# Optionally, you can check the client IP address against the Project Honey Pot
# HTTPBL (dnsbl.httpbl.org). In order to use this, you need to register to get a
# free API key. Set it here with SecHttpBlKey.
#
# Project Honeypot returns multiple different malicious IP types.
# You may specify which you want to block by enabling or disabling them below.
#
# Ref: https://www.projecthoneypot.org/httpbl.php
# Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#wiki-SecHttpBlKey
#
# Uncomment these rules to use this feature:
#
#SecHttpBlKey XXXXXXXXXXXXXXXXX
#SecAction "id:900500,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:tx.block_search_ip=1,\
#  setvar:tx.block_suspicious_ip=1,\
#  setvar:tx.block_harvester_ip=1,\
#  setvar:tx.block_spammer_ip=1"


#
# -- [[ GeoIP Database ]] ------------------------------------------------------
#
# There are some rulesets that inspect geolocation data of the client IP address
# (geoLookup). The CRS uses geoLookup to implement optional country blocking.
#
# To use geolocation, we make use of the MaxMind GeoIP database.
# This database is not included with the CRS and must be downloaded.
#
# There are two formats for the GeoIP database. ModSecurity v2 uses GeoLite (.dat files),
# and ModSecurity v3 uses GeoLite2 (.mmdb files).
#
# If you use ModSecurity 3, MaxMind provides a binary for updating GeoLite2 files,
# see https://github.com/maxmind/geoipupdate.
#
# Download the package for your OS, and read https://dev.maxmind.com/geoip/geoipupdate/
# for configuration options.
#
# Warning: GeoLite (not GeoLite2) databases are considered legacy, and not being updated anymore.
# See https://support.maxmind.com/geolite-legacy-discontinuation-notice/ for more info.
#
# Therefore, if you use ModSecurity v2, you need to regenerate updated .dat files
# from CSV files first.
#
# You can achieve this using https://github.com/sherpya/geolite2legacy
# Pick the zip files from maxmind site:
# https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country-CSV.zip
#
# Follow the guidelines for installing the tool and run:
# ./geolite2legacy.py -i GeoLite2-Country-CSV.zip \
#                     -f geoname2fips.csv -o /usr/share/GeoliteCountry.dat
#
# Update the database regularly, see Step 3 of the configuration link above.
#
# By default, when you execute `sudo geoipupdate` on Linux, files from the free database
# will be downloaded to `/usr/share/GeoIP` (both v1 and v2).
#
# Then choose from:
#   - `GeoLite2-Country.mmdb` (if you are using ModSecurity v3)
#   - `GeoLiteCountry.dat`    (if you are using ModSecurity v2)
#
# Ref: http://blog.spiderlabs.com/2010/10/detecting-malice-with-modsecurity-geolocation-data.html
# Ref: http://blog.spiderlabs.com/2010/11/detecting-malice-with-modsecurity-ip-forensics.html
#
# Uncomment only one of the next rules here to use this feature.
# Choose the one depending on the ModSecurity version you are using, and change the path accordingly:
#
# For ModSecurity v3:
#SecGeoLookupDB /usr/share/GeoIP/GeoLite2-Country.mmdb
# For ModSecurity v2 (points to the converted one):
#SecGeoLookupDB /usr/share/GeoIP/GeoLiteCountry.dat

#
# -=[ Block Countries ]=-
#
# Rules in the IP Reputation file can check the client against a list of high
# risk country codes. These countries have to be defined in the variable
# tx.high_risk_country_codes via their ISO 3166 two-letter country code:
# https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements
#
# If you are sure that you are not getting any legitimate requests from a given
# country, then you can disable all access from that country via this variable.
# The rule performing the test has the rule id 910100.
#
# This rule requires SecGeoLookupDB to be enabled and the GeoIP database to be
# downloaded (see the section "GeoIP Database" above.)
#
# By default, the list is empty. A list used by some sites was the following:
# setvar:'tx.high_risk_country_codes=UA ID YU LT EG RO BG TR RU PK MY CN'"
#
# Uncomment this rule to use this feature:
#
#SecAction \
# "id:900600,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:'tx.high_risk_country_codes='"


#
# -- [[ Anti-Automation / DoS Protection ]] ------------------------------------
#
# Optional DoS protection against clients making requests too quickly.
#
# When a client is making more than 100 requests (excluding static files) within
# 60 seconds, this is considered a 'burst'. After two bursts, the client is
# blocked for 600 seconds.
#
# Requests to static files are not counted towards DoS; they are listed in the
# 'tx.static_extensions' setting, which you can change in this file (see
# section "HTTP Policy Settings").
#
# For a detailed description, see rule file REQUEST-912-DOS-PROTECTION.conf.
#
# Uncomment this rule to use this feature:
#
#SecAction \
# "id:900700,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:'tx.dos_burst_time_slice=60',\
#  setvar:'tx.dos_counter_threshold=100',\
#  setvar:'tx.dos_block_timeout=600'"


#
# -- [[ Check UTF-8 encoding ]] ------------------------------------------------
#
# The CRS can optionally check request contents for invalid UTF-8 encoding.
# We only want to apply this check if UTF-8 encoding is actually used by the
# site; otherwise it will result in false positives.
#
# Uncomment this rule to use this feature:
#
#SecAction \
# "id:900950,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:tx.crs_validate_utf8_encoding=1"


#
# -- [[ Blocking Based on IP Reputation ]] ------------------------------------
#
# Blocking based on reputation is permanent in the CRS. Unlike other rules,
# which look at the individual request, the blocking of IPs is based on
# a persistent record in the IP collection, which remains active for a
# certain amount of time.
#
# There are two ways an individual client can become flagged for blocking:
# - External information (RBL, GeoIP, etc.)
# - Internal information (Core Rules)
#
# The record in the IP collection carries a flag, which tags requests from
# individual clients with a flag named IP.reput_block_flag.
# But the flag alone is not enough to have a client blocked. There is also
# a global switch named tx.do_reput_block. This is off by default. If you set
# it to 1 (=On), requests from clients with the IP.reput_block_flag will
# be blocked for a certain duration.
#
# Variables
# ip.reput_block_flag      Blocking flag for the IP collection record
# ip.reput_block_reason    Reason (= rule message) that caused to blocking flag
# tx.do_reput_block        Switch deciding if we really block based on flag
# tx.reput_block_duration  Setting to define the duration of a block
#
# It may be important to know, that all the other core rules are skipped for
# requests, when it is clear that they carry the blocking flag in question.
#
# Uncomment this rule to use this feature:
#
#SecAction \
# "id:900960,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:tx.do_reput_block=1"
#
# Uncomment this rule to change the blocking time:
# Default: 300 (5 minutes)
#
#SecAction \
# "id:900970,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:tx.reput_block_duration=300"


#
# -- [[ Collection timeout ]] --------------------------------------------------
#
# Set the SecCollectionTimeout directive from the ModSecurity default (1 hour)
# to a lower setting which is appropriate to most sites.
# This increases performance by cleaning out stale collection (block) entries.
#
# This value should be greater than or equal to:
# tx.reput_block_duration (see section "Blocking Based on IP Reputation") and
# tx.dos_block_timeout (see section "Anti-Automation / DoS Protection").
#
# Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#wiki-SecCollectionTimeout

# Please keep this directive uncommented.
# Default: 600 (10 minutes)
SecCollectionTimeout 600


#
# -- [[ End of setup ]] --------------------------------------------------------
#
# The CRS checks the tx.crs_setup_version variable to ensure that the setup
# has been loaded. If you are not planning to use this setup template,
# you must manually set the tx.crs_setup_version variable before including
# the CRS rules/* files.
#
# The variable is a numerical representation of the CRS version number.
# E.g., v3.0.0 is represented as 300.
#
SecAction \
 "id:900990,\
  phase:1,\
  nolog,\
  pass,\
  t:none,\
  setvar:tx.crs_setup_version=320"
1 Like

@bmw could you take a look at a possible Certbot Apache parser concern?

(Fortunately Certbot's parsing has improved to the point where these gotten genuinely uncommon these days, while they used to be one of the most frequent questions on this forum!)

1 Like

Line 176 is this:

#SecAction \
#  "id:900000,\
#   phase:1,\
#   nolog,\
#   pass,\
#   t:none,\
#   setvar:tx.paranoia_level=1"

This reinforces my idea that Certbot is having trouble parsing the \ at the end of the line. You could try removing those lines, since they are commented out anyhow.

Also, Certbot 0.31.0 was released in 2019. It's possible there have been improvements to Certbot's configuration parser since then. Are you able to upgrade to the latest version?

2 Likes

I spent some time trying to recreate this problem and wasn't able to for some reason.

Like Seth said though, we definitely get fewer bug reports about problems like this nowadays. If you'd like to try upgrading to a recent Certbot version to see if it fixes the problem, see https://certbot.eff.org/lets-encrypt/ubuntubionic-apache.

2 Likes
  1. Remove lines crs-setup.conf. Only
    SecAction "id:900990, phase:1, nolog, pass, t:none, setvar:tx.crs_setup_version=320"

  2. Run
    $sudo certbot certonly --apache -d motokits.com.co -d www.motokits.com.co
    Response:

motokits_2020@motokits:~$ sudo certbot certonly --apache -d motokits.com.co -d www.motokits.com.co

Plugins selected: Authenticator apache, Installer apache
Cert is due for renewal, auto-renewing...
Renewing an existing certificate for motokits.com.co and www.motokits.com.co
Performing the following challenges:
http-01 challenge for motokits.com.co
http-01 challenge for www.motokits.com.co
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:

  • Congratulations! Your certificate and chain have been saved at:

    Your key file has been saved at:

    Your certificate will expire on 2021-06-28. To obtain a new or
    tweaked version of this certificate in the future, simply run
    certbot again. To non-interactively renew all of your
    certificates, run "certbot renew"

  1. $sudo systemctl restart apache2
  2. Ok. My site is safe. Thank you.
1 Like