case

Lead requirements

It is well known that HDFS is not authenticated by default, and users can fill in the upload user name when calling HTTPFS to HDFS, which has a large risk for HDFS itself. Because Kerberos security authentication is not enabled, you need to implement this security through a third-party mode. Then there is the simple Auth Basic authentication via Nginx that forces the user to submit user.name equal to the authentication header’s user, i.e. $remote_user.

Simple implementation

upstream hdfs-httpfs {
        server xxxxx:21400;
}

server {
        listen          80;
        server_name     hdfs.xx.xx.xxx;

        auth_basic   auth;
        auth_basic_user_file /etc/nginx/htpasswd/hdfs.xxx.xxx.xx.passwd;

        location / {
                if ( $arg_user.name = "") {
                        set $args '$args&user.name=$remote_user';
                }

                if ( $arg_user.name ! ="$remote_user") {return401; } proxy_pass http://hdfs-httpfs/webhdfs/v1/; }}Copy the code

Hit the pit

Here’s the catch: I thought I could do this by simply changing the value of arg_user.name, as follows

set $arg_user.name $remote_user;
Copy the code

However, it is found that the modification does not take effect, and it is later learned that except for the variable $args, its corresponding child variable values can only be viewed and cannot be modified.

The appendix

Custom variables and built-in predefined variables

Custom variable

Variables can be declared on sever, HTTP,location, etc., using the set command (not unique). The syntax is as follows

set$Variable name Variable valueCopy the code

Nginx’s built-in variables are globally visible. The rules for the visibility of variables declared in different levels of tags are as follows:

  1. The location block is visible in the variable declared in the Location tag
  2. The variables declared in the Server tag are visible to the Server block and all the sub-blocks within the Server block
  3. Variables declared in HTTP tags are visible to the HTTP block and all subblocks within the HTTP block

Built-in list of commonly used variables

The variable name define
$arg_PARAMETER PARAMETER Specifies the value of the variable name PARAMETER in the GET request.
$args This variable is equal to the parameter in the GET request. For example, foo = 123 & bar = blahblah; This variable can be modified
$content_length Content-length field in the request header.
$content_type The Content-Type field in the request header.
$cookie_COOKIE cookie The value of the COOKIE.
$host The Host header field in the request, or if the Host header in the request is unavailable or empty, the name of the server processing the request (the value of the server_name directive for the server processing the request). The value is lowercase and does not contain ports.
$hostname The machine name uses the value of the gethostName system call
$http_HEADER HEADER is the content of the HTTP request. The HEADER is lowercase and the – becomes _(dashes become underscores), for example, $http_user_agent (user-agent value).
$sent_http_HEADER The content of the HTTP response HEADER, whose HEADER is the content of the HTTP response is lowercase and whose – becomes _(dashes become underscores), for example: $sent_http_cache_control(cache-control value)
$is_args If $args is set, the value is “?” Otherwise, “”.
$limit_rate This variable can limit the connection rate.
$query_string Same as $args.
$remote_addr IP address of the client.
$remote_port Port of the client.
$remote_user A user name that has been authenticated by the Auth Basic Module.
$request_filename The file path of the current connection request, generated by the root or Alias directive and the URI request.
$request_uri This variable is equal to the original URI containing some client request parameters. It cannot be modified. See $URI to change or rewrite the URI.
$scheme The protocol used, such as HTTP or HTTPS, such as rewrite ^(.+)scheme://example.com$1 redirect;
$server_addr The server address, which can be determined after a system call, must be specified in LISTEN and use the bind parameter to bypass the system call.
$server_name Server name.
$server_port Port number for the request to arrive at the server.
$server_protocol The protocol used for the request, usually HTTP/1.0 or HTTP/1.1.
$uri The current URI in the request (without the request parameters, which are in args), is different from the args passed by the browser, is different from the value of request_URI passed by the browser, and can be changed either by internal redirection or using the index directive. Protocol and host names are not included, such as /foo/bar.html