implement feature to add basic auth to containers via proxy variable

This commit is contained in:
Joachim Lusiardi 2020-05-29 19:38:50 +02:00
parent 7df3279cea
commit b5faa4c09e
2 changed files with 23 additions and 2 deletions

View File

@ -18,7 +18,7 @@ The following options are possible:
* **ip**(optional, defaults to listen on all IPs) the IP on which the proxy should listen. * **ip**(optional, defaults to listen on all IPs) the IP on which the proxy should listen.
* **location**(optional) if the proxied web application is not running on the /-path * **location**(optional) if the proxied web application is not running on the /-path
* **body_size**(optional, defaults to 1MB) the allowed maximal body size as defined in http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size * **body_size**(optional, defaults to 1MB) the allowed maximal body size as defined in http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size
* **auth_data**(optional, defaults to none) If set, the value must be constructed like `Realm;Username;Password` e.g. `SecretWebsite;admin;$apr1$RR/RTfI.$s7mRx/yKay7g3Jxmg/eMT/`. The crypted password can be created with `htpasswd`: ` htpasswd -n -b admin supersecret`
## Starting the container ## Starting the container
Since the container uses Docker's internal event reporting, it needs access to the daemon. At the Since the container uses Docker's internal event reporting, it needs access to the daemon. At the

View File

@ -10,12 +10,14 @@ import os
import logging import logging
target_path = "/tmp/nginx/" target_path = "/tmp/nginx/"
auth_path = target_path + "auth/"
config_path = target_path + "conf/" config_path = target_path + "conf/"
pid_file = "/var/run/nginx.pid" pid_file = "/var/run/nginx.pid"
non_location_template = """# proxy for container '$containername' non_location_template = """# proxy for container '$containername'
server { server {
listen $listen; listen $listen;
server_name $names; server_name $names;
$auth_config
location / { location / {
client_max_body_size $body_size; client_max_body_size $body_size;
client_body_timeout 300s; client_body_timeout 300s;
@ -32,6 +34,7 @@ location_template = """# proxy for container '$containername'
server { server {
listen $listen; listen $listen;
server_name $names; server_name $names;
$auth_config
location / { location / {
return 301 $$scheme://$name/$location; return 301 $$scheme://$name/$location;
} }
@ -119,6 +122,21 @@ def handle_container(id):
logging.info('container "%s"(%s) does not listen on %s.', extract_name(inspect_data), container_listen_ip, str(listen_ips)) logging.info('container "%s"(%s) does not listen on %s.', extract_name(inspect_data), container_listen_ip, str(listen_ips))
return return
logging.info('container "%s"(%s) is allowed to listen on %s.', extract_name(inspect_data), container_listen_ip, str(listen_ips)) logging.info('container "%s"(%s) is allowed to listen on %s.', extract_name(inspect_data), container_listen_ip, str(listen_ips))
auth_data = get_if_available(proxy_data, 'auth_data', None)
logging.info('auth data: %s', auth_data)
auth_config = ''
if auth_data:
realm, htpasswd = auth_data.split(';', 1)
htpasswd = htpasswd.replace(';', ':')
auth_file_name = auth_path + 'proxy_{id}_{code}'.format(id=id, code=env_key)
with open(auth_file_name, 'w') as file:
file.write(htpasswd)
# write auth data to file
# add to config
auth_config = """
auth_basic "{realm}";
auth_basic_user_file {file};
""".format(realm=realm,file=auth_file_name)
substitutes = { substitutes = {
'containername': '{c} {d}'.format(c=extract_name(inspect_data), d=env_data), 'containername': '{c} {d}'.format(c=extract_name(inspect_data), d=env_data),
'ip': extract_ip(inspect_data), 'ip': extract_ip(inspect_data),
@ -126,7 +144,8 @@ def handle_container(id):
'names': get_if_available(proxy_data, 'server_names', '').replace(';', ' '), 'names': get_if_available(proxy_data, 'server_names', '').replace(';', ' '),
'port': get_if_available(proxy_data, 'port', 80), 'port': get_if_available(proxy_data, 'port', 80),
'body_size': get_if_available(proxy_data, 'body_size', '1m'), 'body_size': get_if_available(proxy_data, 'body_size', '1m'),
'listen': '*:80' 'listen': '*:80',
'auth_config': auth_config
} }
logging.info('writing to %sproxy_%s', config_path, id) logging.info('writing to %sproxy_%s', config_path, id)
with open(config_path + '/proxy_{id}_{code}'.format(id=id,code=env_key), 'w') as file: with open(config_path + '/proxy_{id}_{code}'.format(id=id,code=env_key), 'w') as file:
@ -196,6 +215,8 @@ if __name__ == '__main__':
if not os.path.exists(config_path): if not os.path.exists(config_path):
logging.info('creating target path: %s', target_path) logging.info('creating target path: %s', target_path)
os.mkdir(target_path) os.mkdir(target_path)
logging.info('creating target path: %s', auth_path)
os.mkdir(auth_path)
logging.info('creating target path: %s', config_path) logging.info('creating target path: %s', config_path)
os.mkdir(config_path) os.mkdir(config_path)