Commit 7993ff81 authored by Łukasz Nowak's avatar Łukasz Nowak Committed by Łukasz Nowak

caddy-frontend: Protect against wrong custom config

Even if the master partition owner will authorise given slave for custom
configuration reject this slave in case if it does not pass validation for
snippet.
parent 82cdff12
...@@ -161,10 +161,14 @@ caddy_custom_https ...@@ -161,10 +161,14 @@ caddy_custom_https
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
Raw Caddy configuration in python template format (i.e. write "%%" for one "%") for the slave listening to the https port. Its content will be templatified in order to access functionalities such as cache access, ssl certificates... The list is available above. Raw Caddy configuration in python template format (i.e. write "%%" for one "%") for the slave listening to the https port. Its content will be templatified in order to access functionalities such as cache access, ssl certificates... The list is available above.
*Note*: The system will reject slaves which does not pass validation of caddy configuration, despite them being in ``-frontend-authorized-slave-string``, as otherwise this will lead to the whole frontend to fail.
caddy_custom_http caddy_custom_http
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
Raw Caddy configuration in python template format (i.e. write "%%" for one "%") for the slave listening to the http port. Its content will be templatified in order to access functionalities such as cache access, ssl certificates... The list is available above Raw Caddy configuration in python template format (i.e. write "%%" for one "%") for the slave listening to the http port. Its content will be templatified in order to access functionalities such as cache access, ssl certificates... The list is available above
*Note*: The system will reject slaves which does not pass validation of caddy configuration, despite them being in ``-frontend-authorized-slave-string``, as otherwise this will lead to the whole frontend to fail.
url url
~~~ ~~~
Necessary to activate cache. ``url`` of backend to use. Necessary to activate cache. ``url`` of backend to use.
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
# not need these here). # not need these here).
[template] [template]
filename = instance.cfg.in filename = instance.cfg.in
md5sum = ae708bdef97812bad1223b94fae750b3 md5sum = bce721468b4c16294404cac8b88356c0
[template-common] [template-common]
filename = instance-common.cfg.in filename = instance-common.cfg.in
...@@ -26,7 +26,7 @@ md5sum = 750e2b1c922bf14511a3bc8a42468b1b ...@@ -26,7 +26,7 @@ md5sum = 750e2b1c922bf14511a3bc8a42468b1b
[template-apache-replicate] [template-apache-replicate]
filename = instance-apache-replicate.cfg.in filename = instance-apache-replicate.cfg.in
md5sum = 30a502d56ce0a168aa3feaedbee73c3f md5sum = 3a3dd6c5efeeff7fbc817e48e84e3e84
[template-slave-list] [template-slave-list]
filename = templates/apache-custom-slave-list.cfg.in filename = templates/apache-custom-slave-list.cfg.in
...@@ -52,6 +52,10 @@ md5sum = ed1c086f0548a908661b294e845dc008 ...@@ -52,6 +52,10 @@ md5sum = ed1c086f0548a908661b294e845dc008
filename = templates/caddy-backend-url-validator.in filename = templates/caddy-backend-url-validator.in
md5sum = 0979a03476e86bf038516c9565dadc17 md5sum = 0979a03476e86bf038516c9565dadc17
[caddy-custom-http-validator]
filename = templates/caddy-custom-http-validator.in
md5sum = a264208e960cdcd25ef27ed8cf730240
[template-not-found-html] [template-not-found-html]
filename = templates/notfound.html filename = templates/notfound.html
md5sum = f20d6c3d2d94fb685f8d26dfca1e822b md5sum = f20d6c3d2d94fb685f8d26dfca1e822b
......
...@@ -123,6 +123,7 @@ context = ...@@ -123,6 +123,7 @@ context =
key template_caddy_replicate template-caddy-replicate:target key template_caddy_replicate template-caddy-replicate:target
key template_replicate_publish_slave_information template-replicate-publish-slave-information:target key template_replicate_publish_slave_information template-replicate-publish-slave-information:target
key caddy_backend_url_validator caddy-backend-url-validator:output key caddy_backend_url_validator caddy-backend-url-validator:output
key caddy_custom_http_validator caddy-custom-http-validator:output
section template_frontend_parameter_dict template-frontend-parameter-section section template_frontend_parameter_dict template-frontend-parameter-section
...@@ -138,6 +139,13 @@ filename = caddy-backend-url-validator.in ...@@ -138,6 +139,13 @@ filename = caddy-backend-url-validator.in
output = ${buildout:directory}/caddy-backend-url-validator output = ${buildout:directory}/caddy-backend-url-validator
mode = 0750 mode = 0750
[caddy-custom-http-validator]
recipe = slapos.recipe.template
url = ${:_profile_base_location_}/templates/${:filename}
filename = caddy-custom-http-validator.in
output = ${buildout:directory}/caddy-custom-http-validator
mode = 0750
[template-caddy-replicate] [template-caddy-replicate]
recipe = slapos.recipe.build:download recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/instance-apache-replicate.cfg.in url = ${:_profile_base_location_}/instance-apache-replicate.cfg.in
......
...@@ -74,9 +74,11 @@ context = ...@@ -74,9 +74,11 @@ context =
{% if slave.get(key) %} {% if slave.get(key) %}
{% if not slave.get('slave_reference') in authorized_slave_string %} {% if not slave.get('slave_reference') in authorized_slave_string %}
{% do slave_dict.__setitem__('state', False) %} {% do slave_dict.__setitem__('state', False) %}
{% elif subprocess_module.call([caddy_custom_http_validator, slave[key]]) == 1 %}
{% do slave_dict.__setitem__('state', False) %}
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endfor %} {% endfor %} {# for key in ['caddy_custom_http', 'caddy_custom_https', 'apache_custom_http', 'apache_custom_https'] #}
{% if slave.get('url') %} {% if slave.get('url') %}
{% if subprocess_module.call([caddy_backend_url_validator, slave['url']]) == 1 %} {% if subprocess_module.call([caddy_backend_url_validator, slave['url']]) == 1 %}
{% do slave_dict.__setitem__('state', False) %} {% do slave_dict.__setitem__('state', False) %}
......
...@@ -55,6 +55,7 @@ extra-context = ...@@ -55,6 +55,7 @@ extra-context =
import validators validators import validators validators
key openssl :openssl key openssl :openssl
raw caddy_backend_url_validator {{ caddy_backend_url_validator }} raw caddy_backend_url_validator {{ caddy_backend_url_validator }}
raw caddy_custom_http_validator {{ caddy_custom_http_validator }}
raw template_publish_slave_information {{ template_replicate_publish_slave_information }} raw template_publish_slave_information {{ template_replicate_publish_slave_information }}
# Must match the key id in [switch-softwaretype] which uses this section. # Must match the key id in [switch-softwaretype] which uses this section.
raw software_type RootSoftwareInstance-default-custom-personal-replicate raw software_type RootSoftwareInstance-default-custom-personal-replicate
......
#!${dash:location}/bin/dash
config="$1"
echo -e $config | ${caddy:output} -conf stdin -validate > /dev/null 2>&1
...@@ -3015,8 +3015,7 @@ class TestSlaveBadParameters(SlaveHttpFrontendTestCase, TestDataMixin): ...@@ -3015,8 +3015,7 @@ class TestSlaveBadParameters(SlaveHttpFrontendTestCase, TestDataMixin):
'public-ipv4': LOCAL_IPV4, 'public-ipv4': LOCAL_IPV4,
'apache-certificate': open('wildcard.example.com.crt').read(), 'apache-certificate': open('wildcard.example.com.crt').read(),
'apache-key': open('wildcard.example.com.key').read(), 'apache-key': open('wildcard.example.com.key').read(),
'-frontend-authorized-slave-string': '-frontend-authorized-slave-string': '_caddy_custom_http_s-reject',
'_apache_custom_http_s-accepted _caddy_custom_http_s-accepted',
'port': HTTPS_PORT, 'port': HTTPS_PORT,
'plain_http_port': HTTP_PORT, 'plain_http_port': HTTP_PORT,
'nginx_port': NGINX_HTTPS_PORT, 'nginx_port': NGINX_HTTPS_PORT,
...@@ -3029,6 +3028,16 @@ class TestSlaveBadParameters(SlaveHttpFrontendTestCase, TestDataMixin): ...@@ -3029,6 +3028,16 @@ class TestSlaveBadParameters(SlaveHttpFrontendTestCase, TestDataMixin):
@classmethod @classmethod
def getSlaveParameterDictDict(cls): def getSlaveParameterDictDict(cls):
return { return {
'caddy_custom_http_s-reject': {
'caddy_custom_https': """DestroyCaddyHttps
For sure
This shall not be valid
https://www.google.com {}""",
'caddy_custom_http': """DestroyCaddyHttp
For sure
This shall not be valid
https://www.google.com {}""",
},
're6st-optimal-test-nocomma': { 're6st-optimal-test-nocomma': {
're6st-optimal-test': 'nocomma', 're6st-optimal-test': 'nocomma',
}, },
...@@ -3081,11 +3090,11 @@ class TestSlaveBadParameters(SlaveHttpFrontendTestCase, TestDataMixin): ...@@ -3081,11 +3090,11 @@ class TestSlaveBadParameters(SlaveHttpFrontendTestCase, TestDataMixin):
'monitor-base-url': None, 'monitor-base-url': None,
'domain': 'example.com', 'domain': 'example.com',
'accepted-slave-amount': '8', 'accepted-slave-amount': '8',
'rejected-slave-amount': '3', 'rejected-slave-amount': '4',
'slave-amount': '11', 'slave-amount': '12',
'rejected-slave-list': 'rejected-slave-list':
'["_server-alias-unsafe", "_custom_domain-unsafe", ' '["_caddy_custom_http_s-reject", "_ssl_key-ssl_crt-unsafe", '
'"_ssl_key-ssl_crt-unsafe"]'} '"_custom_domain-unsafe", "_server-alias-unsafe"]'}
self.assertEqual( self.assertEqual(
expected_parameter_dict, expected_parameter_dict,
...@@ -3395,3 +3404,11 @@ class TestSlaveBadParameters(SlaveHttpFrontendTestCase, TestDataMixin): ...@@ -3395,3 +3404,11 @@ class TestSlaveBadParameters(SlaveHttpFrontendTestCase, TestDataMixin):
parameter_dict, parameter_dict,
{} {}
) )
def test_caddy_custom_http_s_reject(self):
parameter_dict = self.slave_connection_parameter_dict_dict[
'caddy_custom_http_s-reject']
self.assertEqual(
parameter_dict,
{}
)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment