Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions mig/install/apache-MiG-template.conf
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,12 @@ Alias /status-events.json "__MIG_STATE__/wwwpublic/status-events.json"
</FilesMatch>
</IfModule>

# Optional resource hogging prevention with default request timeouts.
# Helps protect against slowloris-style attacks gradually depleting resources
<IfModule mod_reqtimeout.c>
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>

<IfModule mod_mime.c>
# NOTE: workaround for broken double gzip decompression e.g. in Firefox.
# The bam files are in fact already gzip files and require care:
Expand Down
3 changes: 3 additions & 0 deletions mig/install/apache-mimic-deb-template.conf
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ __JUPYTER_COMMENTED__ LoadModule lbmethod_byrequests_module modules/mod_lbmethod
# Optional Header mangling if requested (for HSTS)
__HSTS_COMMENTED__ LoadModule headers_module modules/mod_headers.so

# Optional resource hogging prevention if requested (for mod reqtimeout)
__REQTIMEOUT_COMMENTED__ LoadModule reqtimeout_module modules/mod_reqtimeout.so

# Apparently we need this mime setup on Redhat to just run apache
TypesConfig /etc/mime.types
MIMEMagicFile conf/magic
Expand Down
9 changes: 9 additions & 0 deletions mig/shared/install.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
Expand All @@ -20,7 +20,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Check warning on line 23 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (81 > 80 characters)

Check warning on line 23 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (81 > 80 characters)
#
# -- END_HEADER ---
#
Expand Down Expand Up @@ -49,7 +49,7 @@
import subprocess
import sys

from mig.shared.base import force_native_str, force_utf8

Check failure on line 52 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused import 'force_utf8' (90% confidence)

Check failure on line 52 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused import 'force_utf8' (90% confidence)
from mig.shared.defaults import default_http_port, default_https_port, \
auth_openid_mig_db, auth_openid_ext_db, MIG_BASE, STRONG_TLS_CIPHERS, \
STRONG_TLS_CURVES, STRONG_SSH_HOSTKEYALGOS, STRONG_SSH_KEXALGOS, \
Expand All @@ -62,11 +62,11 @@
from mig.shared.fileio import read_file, read_file_lines, write_file, \
write_file_lines
from mig.shared.htmlgen import menu_items
from mig.shared.jupyter import gen_balancer_proxy_template, gen_openid_template, \

Check warning on line 65 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (82 > 80 characters)

Check warning on line 65 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (82 > 80 characters)
gen_rewrite_template
from mig.shared.pwcrypto import password_requirements, make_simple_hash, \
make_safe_hash
from mig.shared.safeeval import subprocess_call, subprocess_popen, subprocess_pipe

Check failure on line 69 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused import 'subprocess_call' (90% confidence)

Check warning on line 69 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (82 > 80 characters)

Check failure on line 69 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused import 'subprocess_call' (90% confidence)

Check warning on line 69 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (82 > 80 characters)
from mig.shared.safeinput import valid_alphanumeric, InputException
from mig.shared.url import urlparse

Expand All @@ -88,9 +88,9 @@
def transform_str_to_dict(input_str):
"""
Transforms a string input into a Python literal or container.
The function will only return the transformed object if it becomes a dictionary.

Check warning on line 91 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (84 > 80 characters)

Check warning on line 91 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (84 > 80 characters)
input_str: The input string that is expected to be
structured as a dictionary. A valid input_str for example could be '{'hello': 'world'}'.

Check warning on line 93 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (93 > 80 characters)

Check warning on line 93 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (93 > 80 characters)
"""
try:
output_dict = ast.literal_eval(input_str)
Expand All @@ -102,10 +102,10 @@
return output_dict


def determine_timezone(_environ=os.environ, _path_exists=os.path.exists, _print=print):

Check warning on line 105 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (87 > 80 characters)

Check warning on line 105 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (87 > 80 characters)
"""Attempt to detect the timezone in various known portable ways."""

sys_timezone = None

Check failure on line 108 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused variable 'sys_timezone' (60% confidence)

Check failure on line 108 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused variable 'sys_timezone' (60% confidence)

timezone_link = '/etc/localtime'
timezone_cmd = ["/usr/bin/timedatectl", "status"]
Expand Down Expand Up @@ -167,7 +167,7 @@


def fill_template(template_file, output_file, settings, eat_trailing_space=[],
additional=None):

Check failure on line 170 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused variable 'additional' (100% confidence)

Check failure on line 170 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused variable 'additional' (100% confidence)
"""Fill a configuration template using provided settings dictionary"""
contents = read_file(template_file, None)
if contents is None:
Expand All @@ -179,7 +179,7 @@
for (variable, value) in settings.items():
suffix = ''
if variable in eat_trailing_space:
suffix = '\s{0,1}'

Check warning on line 182 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

invalid escape sequence '\s'

Check warning on line 182 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

invalid escape sequence '\s'
try:
contents = re.sub(variable + suffix, value, contents)
except Exception as exc:
Expand All @@ -199,10 +199,10 @@
""" Insert into a configuration template using provided settings dictionary
:param template_file: path to the template configuration file that should be
modified with inserts
:param insert_identifiers: dictionary, where the keys are used as search strings

Check warning on line 202 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (84 > 80 characters)

Check warning on line 202 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (84 > 80 characters)
to find the index where the insert should take place. The values can either be a list

Check warning on line 203 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (89 > 80 characters)

Check warning on line 203 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (89 > 80 characters)
of a single string
:param unique: Whether the function should check whether the supplied value is

Check warning on line 205 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (82 > 80 characters)

Check warning on line 205 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

line too long (82 > 80 characters)
already present in the template_file, if so it won't insert it
:return: True/False based on whether an insert took place
"""
Expand Down Expand Up @@ -300,7 +300,7 @@
]


def generate_confs(

Check failure on line 303 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused function 'generate_confs' (60% confidence)

Check failure on line 303 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused function 'generate_confs' (60% confidence)
generateconfs_output_path,
# NOTE: make sure command line args with white-space are properly wrapped
generateconfs_command=subprocess.list2cmdline(sys.argv),
Expand Down Expand Up @@ -382,6 +382,7 @@
enable_jupyter=False,
enable_cloud=False,
enable_hsts=True,
enable_reqtimeout=False,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should consider naming this 'enable_http_reqtimeout' or 'enable_apache_reqtimeout' to keep the namespace open for other types of 'reqtimeout' options ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reviewing.
I did in fact start out with an apache_ prefix here and on the mod_evasive PR #389 but dropped it again looking at how enable_wsgi, enable_hsts, enable_openid, etc. are very similar for other Apache modules. I agree that it is perhaps ambiguous and to general here - although one could cheekily say the same about enable_quota ;-)

Perhaps we should again call this what it does rather than what it uses for the purpose? E.g. enable_slowloris_guard.

The same decision will be relevant for the QoS module addition we talked about off-list, btw.

enable_vhost_certs=False,
enable_verify_certs=False,
enable_seafile=False,
Expand Down Expand Up @@ -708,6 +709,7 @@
enable_jupyter,
enable_cloud,
enable_hsts,
enable_reqtimeout,
enable_vhost_certs,
enable_verify_certs,
enable_seafile,
Expand Down Expand Up @@ -964,6 +966,7 @@
user_dict['__ENABLE_JUPYTER__'] = "%s" % enable_jupyter
user_dict['__ENABLE_CLOUD__'] = "%s" % enable_cloud
user_dict['__ENABLE_HSTS__'] = "%s" % enable_hsts
user_dict['__ENABLE_REQTIMEOUT__'] = "%s" % enable_reqtimeout
user_dict['__ENABLE_VHOST_CERTS__'] = "%s" % enable_vhost_certs
user_dict['__ENABLE_VERIFY_CERTS__'] = "%s" % enable_verify_certs
user_dict['__ENABLE_SEAFILE__'] = "%s" % enable_seafile
Expand Down Expand Up @@ -1356,6 +1359,12 @@
else:
user_dict['__HSTS_COMMENTED__'] = '#'

# Enable reqtimeout module to limit resource use if explicitly requested
if user_dict['__ENABLE_REQTIMEOUT__'].lower() == 'true':
user_dict['__REQTIMEOUT_COMMENTED__'] = ''
else:
user_dict['__REQTIMEOUT_COMMENTED__'] = '#'

# Enable vhost-specific certificates only if explicitly requested
if user_dict['__ENABLE_VHOST_CERTS__'].lower() == 'true':
user_dict['__VHOSTCERTS_COMMENTED__'] = ''
Expand Down Expand Up @@ -1510,7 +1519,7 @@

if user_dict['__ENABLE_JUPYTER__'].lower() == 'true':
try:
import requests

Check failure on line 1522 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused import 'requests' (90% confidence)

Check failure on line 1522 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused import 'requests' (90% confidence)
except ImportError:
print("ERROR: jupyter use requested but requests is not installed!")
sys.exit(1)
Expand Down Expand Up @@ -1669,7 +1678,7 @@

if user_dict['__ENABLE_CLOUD__'].lower() == 'true':
try:
import openstack

Check failure on line 1681 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused import 'openstack' (90% confidence)

Check failure on line 1681 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused import 'openstack' (90% confidence)
except ImportError:
print("ERROR: cloud use requested but openstack is not installed!")
sys.exit(1)
Expand Down Expand Up @@ -1790,7 +1799,7 @@
# Enable 2FA only if explicitly requested
if user_dict['__ENABLE_TWOFACTOR__'].lower() == 'true':
try:
import pyotp

Check failure on line 1802 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused import 'pyotp' (90% confidence)

Check failure on line 1802 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused import 'pyotp' (90% confidence)
except ImportError:
print("ERROR: twofactor use requested but pyotp is not installed!")
sys.exit(1)
Expand Down Expand Up @@ -1820,7 +1829,7 @@
# Enable cracklib only if explicitly requested and installed
if user_dict['__ENABLE_CRACKLIB__'].lower() == 'true':
try:
import cracklib

Check failure on line 1832 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused import 'cracklib' (90% confidence)

Check failure on line 1832 in mig/shared/install.py

View workflow job for this annotation

GitHub Actions / Style check python and annotate

unused import 'cracklib' (90% confidence)
except ImportError:
print("ERROR: cracklib use requested but lib is not installed!")
sys.exit(1)
Expand Down
6 changes: 6 additions & 0 deletions tests/fixture/confs-stdlocal/MiG.conf
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,12 @@ Alias /status-events.json "/home/mig/state/wwwpublic/status-events.json"
</FilesMatch>
</IfModule>

# Optional resource hogging prevention with default request timeouts.
# Helps protect against slowloris-style attacks gradually depleting resources
<IfModule mod_reqtimeout.c>
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>

<IfModule mod_mime.c>
# NOTE: workaround for broken double gzip decompression e.g. in Firefox.
# The bam files are in fact already gzip files and require care:
Expand Down
3 changes: 3 additions & 0 deletions tests/fixture/confs-stdlocal/mimic-deb.conf
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ LoadModule wsgi_module modules/mod_wsgi.so
# Optional Header mangling if requested (for HSTS)
LoadModule headers_module modules/mod_headers.so

# Optional resource hogging prevention if requested (for mod reqtimeout)
#LoadModule reqtimeout_module modules/mod_reqtimeout.so

# Apparently we need this mime setup on Redhat to just run apache
TypesConfig /etc/mime.types
MIMEMagicFile conf/magic
Expand Down