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.
* **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
* **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
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
target_path = "/tmp/nginx/"
auth_path = target_path + "auth/"
config_path = target_path + "conf/"
pid_file = "/var/run/nginx.pid"
non_location_template = """# proxy for container '$containername'
server {
listen $listen;
server_name $names;
$auth_config
location / {
client_max_body_size $body_size;
client_body_timeout 300s;
@ -32,6 +34,7 @@ location_template = """# proxy for container '$containername'
server {
listen $listen;
server_name $names;
$auth_config
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))
return
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 = {
'containername': '{c} {d}'.format(c=extract_name(inspect_data), d=env_data),
'ip': extract_ip(inspect_data),
@ -126,7 +144,8 @@ def handle_container(id):
'names': get_if_available(proxy_data, 'server_names', '').replace(';', ' '),
'port': get_if_available(proxy_data, 'port', 80),
'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)
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):
logging.info('creating target path: %s', 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)
os.mkdir(config_path)