diff --git a/docker-compose.yml b/docker-compose.yml index 4258ed7..416c9bf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,6 +10,8 @@ services: - POSTGRES_USER=ttrss - POSTGRES_PASSWORD=password-dev - POSTGRES_DB=ttrss + ports: + - 5432:5432 tt-rss: image: feedati/tt-rss:latest @@ -58,6 +60,8 @@ services: container_name: feedati_webserver volumes: - ./docker/frontend-apache.conf:/usr/local/apache2/conf/httpd.conf:ro + - ./docker/frontend-apache/:/etc/apache2/:ro + - ./docker/frontend-login/:/var/www/login/:ro ports: - 80:80 depends_on: diff --git a/docker/frontend-apache.conf b/docker/frontend-apache.conf index befe9ff..e695633 100644 --- a/docker/frontend-apache.conf +++ b/docker/frontend-apache.conf @@ -10,7 +10,7 @@ LoadModule mime_module modules/mod_mime.so LoadModule log_config_module modules/mod_log_config.so LoadModule env_module modules/mod_env.so #LoadModule expires_module modules/mod_expires.so -#LoadModule headers_module modules/mod_headers.so +LoadModule headers_module modules/mod_headers.so #LoadModule setenvif_module modules/mod_setenvif.so #LoadModule remoteip_module modules/mod_remoteip.so LoadModule proxy_module modules/mod_proxy.so @@ -20,7 +20,18 @@ LoadModule status_module modules/mod_status.so LoadModule autoindex_module modules/mod_autoindex.so LoadModule dir_module modules/mod_dir.so LoadModule alias_module modules/mod_alias.so -#LoadModule rewrite_module modules/mod_rewrite.so + +LoadModule session_module modules/mod_session.so +LoadModule session_crypto_module modules/mod_session_crypto.so +LoadModule session_cookie_module modules/mod_session_cookie.so +LoadModule request_module modules/mod_request.so +LoadModule authz_user_module modules/mod_authz_user.so +LoadModule auth_form_module modules/mod_auth_form.so +LoadModule authn_file_module modules/mod_authn_file.so +# LoadModule authn_dbm_module modules/mod_authn_dbm.so + +LoadModule macro_module modules/mod_macro.so +LoadModule rewrite_module modules/mod_rewrite.so # @@ -39,37 +50,38 @@ ServerAdmin you@example.com ServerName feedati-fe:80 + + AuthFormLoginRequiredLocation "/login/" + AuthFormLoginRequiredLocation "/login/" + AuthFormProvider file +# authn + AuthFormProvider file + AuthUserFile /etc/apache2/passwords.txt +# form + AuthType form + AuthName "authenticationform" +# mod_session + Session On + SessionCookieName session path=/;httponly + SessionCryptoPassphrase changeme!really! + + + +SetHandler form-login-handler +Use Auth +AuthFormLoginSuccessLocation "/tt-rss/" + + AllowOverride none Require all denied -DocumentRoot "/usr/local/apache2/htdocs" - - # - # Possible values for the Options directive are "None", "All", - # or any combination of: - # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews - # - # Note that "MultiViews" must be named *explicitly* --- "Options All" - # doesn't give it to you. - # - # The Options directive is both complicated and important. Please see - # http://httpd.apache.org/docs/2.4/mod/core.html#options - # for more information. - # - Options Indexes FollowSymLinks - - # - # AllowOverride controls what directives may be placed in .htaccess files. - # It can be "All", "None", or any combination of the keywords: - # AllowOverride FileInfo AuthConfig Limit - # +DocumentRoot "/var/www" + + Options None AllowOverride None - - # - # Controls who can get stuff from this server. - # + Use Auth Require all granted @@ -180,11 +192,17 @@ ProxyPreserveHost On ProxyPass http://tt-rss/tt-rss/ ProxyPassReverse http://tt-rss/tt-rss/ +Use Auth +Require valid-user +RewriteEngine on +RewriteRule .* - [E=RU:%{LA-U:REMOTE_USER},NS] +RequestHeader set X-Forwarded-User %{RU}e ProxyPass http://rss-bridge/ ProxyPassReverse http://rss-bridge/ +Require all granted # vim: set ft=apache bkc=yes: diff --git a/docker/frontend-apache/passwords.txt b/docker/frontend-apache/passwords.txt new file mode 100644 index 0000000..1a1c6ad --- /dev/null +++ b/docker/frontend-apache/passwords.txt @@ -0,0 +1 @@ +admin:$2y$05$tPaBuT/mWQCvfk1C12PmV.0Dz8kt0cY1jcD53OGCN26Y8dX2kRPs. diff --git a/docker/frontend-login/index.html b/docker/frontend-login/index.html new file mode 100644 index 0000000..8ff1c8b --- /dev/null +++ b/docker/frontend-login/index.html @@ -0,0 +1,31 @@ + + + + Login required + + + + + +
+

Feedati login

+
+ + + +
+
+ + diff --git a/docker/ttrss-config.php b/docker/ttrss-config.php index 868270e..2cf3e36 100644 --- a/docker/ttrss-config.php +++ b/docker/ttrss-config.php @@ -175,7 +175,7 @@ // if you experience weird errors and tt-rss failing to start, blank pages // after login, or content encoding errors, disable it. - define('PLUGINS', 'auth_internal, note'); + define('PLUGINS', 'auth_proxy, note'); // Comma-separated list of plugins to load automatically for all users. // System plugins have to be specified here. Please enable at least one // authentication plugin here (auth_*). @@ -196,4 +196,6 @@ // Expected config version. Please update this option in config.php // if necessary (after migrating all new options from this file). + define('AUTHPROXY_WHITELIST_NAME', 'feedati-fe'); + // vim:ft=php bkc=yes: diff --git a/dodo.py b/dodo.py index 1cc3ef5..af562bf 100644 --- a/dodo.py +++ b/dodo.py @@ -5,7 +5,7 @@ from doit.tools import LongRunning from dodo_utils import wait_net_service, wait_pgsql_db, \ up2date_hasimage, up2date_anyimages, \ - run_task_func + run_task_func, scan_dir COMPOSE = 'docker-compose -p feedati' DOIT_CONFIG = {'default_tasks': ['up']} @@ -17,8 +17,7 @@ def task_build(): 'uptodate': [up2date_anyimages], 'file_dep': ['docker-compose.yml', 'rss-bridge/Dockerfile', - ] + [os.path.join('docker', fname) - for fname in os.listdir('docker')], + ] + list(scan_dir('docker')), 'actions': [COMPOSE + ' build'], 'clean': [run_task_func(task__build_rm), run_task_func(task__build_rmi)], diff --git a/dodo_utils.py b/dodo_utils.py index 215821c..66e3165 100644 --- a/dodo_utils.py +++ b/dodo_utils.py @@ -1,5 +1,7 @@ import subprocess import time +import os +import fnmatch from doit import loader @@ -32,10 +34,12 @@ def wait_net_service(server, port, timeout=None): # this exception occurs only if timeout is set if timeout: return False + except (ConnectionRefusedError, ConnectionAbortedError): + pass except socket.error as err: # catch timeout exception from underlying network library # this one is different from socket.timeout - if type(err.args) != tuple or err[0] != errno.ETIMEDOUT: + if type(err.args) != tuple or err.errno != errno.ETIMEDOUT: raise else: s.close() @@ -105,3 +109,11 @@ def run_task_func(taskf): if tasks: fun.__doc__ = '\n'.join(t.doc for t in tasks) return fun + + +def scan_dir(dirname, extension=None): + if extension is None: + extension = '*' + for root, dirnames, filenames in os.walk(dirname): + for fname in fnmatch.filter(filenames, extension): + yield os.path.join(root, fname)