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:
- The location block is visible in the variable declared in the Location tag
- The variables declared in the Server tag are visible to the Server block and all the sub-blocks within the Server block
- 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 |