ngx_aws_auth
ngx_aws_auth copied to clipboard
Module breaks core nginx functionality
Compiling nginx with latest ngx_aws_auth module breaks core nginx functionality.
Given test vhost below (example straight from nginx documentation), expectation is that nginx will respond with authorization request. With module compiled in, access is allowed unconditionally.
Tests with module version 1.1.1 work as expected. Examples below use module from master branch.
Test vhost
server {
listen *:80;
server_name example.com;
root /var/www/;
location / {
satisfy any;
allow 1.2.3.4;
deny all;
auth_basic "Zone";
auth_basic_user_file /var/www/.htpasswd;
}
}
nginx 1.10.3 without ngx_aws_auth
Nginx version
# ./nginx-1.10.3 -V
nginx version: nginx/1.10.3
built by gcc 4.9.2 (Debian 4.9.2-10)
configure arguments:
Example request
# curl -ILH "Host: example.com" localhost
HTTP/1.1 401 Unauthorized
Server: nginx/1.10.3
Date: Thu, 02 Feb 2017 10:09:31 GMT
Content-Type: text/html
Content-Length: 195
Connection: keep-alive
WWW-Authenticate: Basic realm="Zone"
nginx 1.10.3 with ngx_aws_auth
Nginx version
# ./nginx-1.10.3-aws -V
nginx version: nginx/1.10.3
built by gcc 4.9.2 (Debian 4.9.2-10)
configure arguments: --add-module=../ngx_aws_auth/
Example request
# curl -ILH "Host: example.com" localhost
HTTP/1.1 200 OK
Server: nginx/1.10.3
Date: Thu, 02 Feb 2017 10:10:53 GMT
Content-Type: text/html
Content-Length: 0
Last-Modified: Thu, 02 Feb 2017 09:29:56 GMT
Connection: keep-alive
ETag: "5892fc14-0"
Accept-Ranges: bytes
FYI, I just tested the commit before the 2.0.0 tag which was successful, and the commit after failed. Looks like the v4 rewrite is at fault.
I took a quick look, and it seems it's because ngx_http_aws_proxy_sign returns NGX_OK if module is not configured. And documentation for satisfy says:
Allows access if all (all) or at least one (any) of the ngx_http_access_module, ngx_http_auth_basic_module, ngx_http_auth_request_module, or ngx_http_auth_jwt_module modules allow access.
Module wedges itself into NGX_HTTP_ACCESS_PHASE handlers and returns OK for requests it should not even be handling. At least that's how I see it.
@weshmashian can we close this issue as #42 should have fixed this?
The case presented in initial report is fixed:
# curl -ILH "Host: example.com" localhost
HTTP/1.1 401 Unauthorized
Server: nginx/1.10.3
Date: Sun, 19 Mar 2017 20:32:21 GMT
Content-Type: text/html
Content-Length: 195
Connection: keep-alive
WWW-Authenticate: Basic realm="Zone"
# curl -ILH "Host: example.com" localhost --user testuser:testpassword
HTTP/1.1 200 OK
Server: nginx/1.10.3
Date: Sun, 19 Mar 2017 20:32:28 GMT
Content-Type: text/html
Content-Length: 0
Last-Modified: Thu, 02 Feb 2017 09:29:56 GMT
Connection: keep-alive
ETag: "5892fc14-0"
Accept-Ranges: bytes
However, if we add aws_sign without configuring the key or any of the other variables, we get the same broken behaviour back:
server {
listen *:80;
server_name example.com;
root /var/www/;
location / {
satisfy any;
auth_basic "Zone";
auth_basic_user_file /var/www/.htpasswd;
aws_sign;
allow 1.2.3.4;
deny all;
}
}
# curl -ILH "Host: example.com" localhost
HTTP/1.1 200 OK
Server: nginx/1.10.3
Date: Sun, 19 Mar 2017 20:45:08 GMT
Content-Type: text/html
Content-Length: 0
Last-Modified: Thu, 02 Feb 2017 09:29:56 GMT
Connection: keep-alive
ETag: "5892fc14-0"
Accept-Ranges: bytes
# curl -ILH "Host: example.com" localhost --user testuser:wrongpassword
HTTP/1.1 200 OK
Server: nginx/1.10.3
Date: Sun, 19 Mar 2017 20:49:55 GMT
Content-Type: text/html
Content-Length: 0
Last-Modified: Thu, 02 Feb 2017 09:29:56 GMT
Connection: keep-alive
ETag: "5892fc14-0"
Accept-Ranges: bytes
Lack of config sanity checks might be a separate issue, but I still do not consider this fixed. IMHO, a module meddling with authentication should not be suffering from these kinds of bugs, especially in v2.
We've purged the module from our builds soon after this was reported, so I can only help with checking the basic interactions and loopholes like the ones above.
I seem to have tripped on this, or a related issue, when trying to have conditional auth_basic in addition to aws auth.
set $auth_basic "Hi";
if ($some_variable = 1) {
set $auth_basic off;
}
auth_basic $auth_basic;
Results in 401 from S3 when the if passes.
Also requires proxy_set_header Authorization "";, lest S3 complains with A header you provided implies functionality that is not implemented