While “allow,deny” and “Allow from all” are allowed to be mixed with the new directives of apache 2.4, it is discouraged.
With the Require Directive the order is important (see Authentication and Authorization - Apache HTTP Server Version 2.4) the Require directive not only specifies which authorization methods should be used, it also specifies the order in which they are called. Multiple authorization methods are called in the same order in which the Require directives appear in the configuration.
Hence, we also don’t need the Satisfy Directive anymore:
<Files "*">
AuthType Basic
AuthName "Piwik"
# to be explicit, state the provider
AuthBasicProvider file
AuthUserFile /{PATH}/.htpasswd
Require valid-user
</Files>
# Allow external access to piwik.php and piwik.js and robots.txt
<FilesMatch "(^piwik\.(php|js)|robots\.txt)">
Require all granted
</FilesMatch>
# Allow Opt-Out
<Files "index.php">
<If "(%{QUERY_STRING} == 'module=CoreAdminHome&action=optOut')">
Require all granted
</If>
</Files>
P.S. Somehow the “OptOut” part got twice in your answer. In one of that parts Files is closed with FilesMatch - which would throw an error! Therefore I put the whole entry here again.
Firstly, thanks a lot @bpit@HuffinPuffin for your well working solution
Just to let you know :
it seems that in last Matomo version, the piwik.js was renamed matomo.js. Unfortunately it will popup an Apache Authentication window to any user who just display your website …
that optOut option uses a new file optOut.js which shouldn’t be blocked by Apache
-all the request to matomo will get 401, all the requests to matomo.php , matomo.js , piwik.php , piwik.js , and also to the URL index.php?module=CoreAdminHome&action=optOut will be allowed with http code 200
I tried a solution inspired by the Apache 2.4 suggestion of @goodspeedal at Using .htaccess to restrict access , modified to restrict Matomo by IP and only allow specific public files.
(note: I’ve replaced the server IP and my IP with placeholder text below)
<Files "*">
# Allow localhost IPv4 IPv6
Require ip 127.0.0.1 ::1
# Allow server IPv4 IPv6
Require ip <server_IPv4> <server_IPv6>
# Allow my IP
Require ip <my_IP>
</Files>
# Allow public access to basic Matomo files
<FilesMatch "(^piwik\.(php|js)|^matomo\.(php|js)|^container_.*\.js|robots\.txt|optOut.js)">
Require all granted
</FilesMatch>
This example works fine for access from the browser, however, the auto-archiving cron job for Matomo fails… Even though the server IP and localhost are both allowed.
Any ideas to allow access for the archiving cron job, as well?
Not really sure your meaning, as the the crontab is using php to execute internal command without to go/request via the web, (neither related to Apache). So just follow the intructions to create crontab will be work. https://matomo.org/docs/setup-auto-archiving/
The cron job parameter --url wants a URL, correct?
Manually performing the cron job outputs errors, a fragment mentioning the exact HTML content of a 403 Forbidden page (see below). When I comment out the Require ip ... from the .htaccess file, the cron job works fine.
Error: Got invalid response from API request: ?module=API&method=API.get&idSite=2&period=day&date=last2&format=php&trigger=archivephp. Response was '<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>403 Forbidden</title> <link rel="stylesheet" href="/error_docs/styles.css"> </head> <body> <div class="page"> <div class="main"> <h1>Server Error</h1> <div class="error-code">403</div> <h2>Forbidden</h2> <p class="lead">You do not have permission to access this document.</p> <hr/> <p>That's what you can do</p> <div class="help-actions"> <a href="javascript:location.reload();">Reload Page</a> <a href="javascript:history.back();">Back to Previous Page</a> <a href="/">Home Page</a> </div> </div> </div> </body> </html>'
The cron job does access the HTTP API, so I’d recommend you to look into the webserver log to see how exactly the rule is blocking the request (I know nothing about Apache, so I can’t be more specific)
Thanks Lukas, I’ve checked the Apache error_log for the domain and found that the HTTP API uses IP address 0.0.0.0, so I’ve changed my .htaccess to something like:
<Files "*">
# Allow localhost IPv4 IPv6
Require ip 127.0.0.1 ::1
# Allow HTTP API
Require ip 0.0.0.0
# Allow admin IP
Require ip <my_IP>
</Files>
# Allow public access to basic Matomo files
<FilesMatch "(^piwik\.(php|js)|^matomo\.(php|js)|^container_.*\.js|robots\.txt|optOut.js)">
Require all granted
</FilesMatch>
Now it works without issues.
PS I probably won’t have to allow localhost, but it doesn’t hurt.
Please check that the requests are still blocked for other domains. At least on some systems 0.0.0.0 matches all IP addresses, so this might allow everyone to access the URLs.
I think I’m a bit lost with this right now. Can some please post the updated full .htaccess configuration for password restricted access that fulfills all requirements?
Allow external access to the files:
matomo.php
matomo.js
piwik.php
piwik.js
plugins/CoreAdminHome/javascripts/optOut.js
favicon.ico (and misc/user/favicon.png ?)
js/container_*.js
plugins/HeatmapSessionRecording/configs.php
Allow external access to the URL:
index.php?module=CoreAdminHome&action=optOut
Allow the cron job (/path/to/matomo/console core:archive --url=http://example.org/) to be run.
For anyone that has issues running the command with --url=https://example.com when you have a password setup on .htaccess you can check this https://matomo.org/faq/mobile-app/faq_16336/ and use the url with the password like: --url=https://user:password@example.com and the command will run without any errors.