修改nginx args变量实现后端转发

案例

前置需求

总所周知hdfs默认是没有鉴权的操做,而用户经过调用httpfs对hdfs进行操做时,能够随便填写上传用户名,这样对hdfs自己而言存在着较大的风险性。因为没有开启Kerberos安全认证,故须要借助第三方的方式来实现此安全性。 因而就有了经过nginx简单的auth basic认证,强制用户提交的user.name等于认证header的user,也就是$remote_user。html

简单实现

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" ){
                        return 401;
                }

                proxy_pass http://hdfs-httpfs/webhdfs/v1/;
                }
        }
复制代码

踩坑

这里有个比较坑的点,本来觉得经过简单修改 arg_user.name的值就能够实现此需求了,以下nginx

set $arg_user.name $remote_user;
复制代码

可是发现修改后并不生效,后来才知道除了变量$args能够被修改之外,其对应的子变量值都只能被查看而不能进行修改。web

附录

自定义变量与内置预约义变量

自定义变量

能够在sever,http,location等标签中使用set命令(非惟一)声明变量,语法以下浏览器

set $变量名 变量值
复制代码

nginx的内置变量是全局可见的,在不一样层级的标签中声明的变量性的可见性规则以下:安全

  1. location标签中声明的变量中对这个location块可见
  2. server标签中声明的变量对server块以及server块中的全部子块可见
  3. http标签中声明的变量对http块以及http块中的全部子块可见

内置经常使用变量列表

变量名 定义
$arg_PARAMETER GET请求中变量名PARAMETER参数的值。
$args 这个变量等于GET请求中的参数。例如,foo=123&bar=blahblah;这个变量能够被修改
$content_length 请求头中的Content-length字段。
$content_type 请求头中的Content-Type字段。
$cookie_COOKIE cookie COOKIE的值。
$host 请求中的主机头(Host)字段,若是请求中的主机头不可用或者空,则为处理请求的server名称(处理请求的server的server_name指令的值)。值为小写,不包含端口。
$hostname 机器名使用 gethostname系统调用的值
$http_HEADER HTTP请求头中的内容,HEADER为HTTP请求中的内容转为小写,-变为_(破折号变为下划线),例如:$http_user_agent ( User-Agent的值 )
$sent_http_HEADER HTTP响应头中的内容,HEADER为HTTP响应中的内容转为小写,-变为_(破折号变为下划线),例如: $sent_http_cache_control( Cache-Control的值 )
$is_args 若是$args设置,值为"?",不然为""。
$limit_rate 这个变量能够限制链接速率。
$query_string 与$args相同。
$remote_addr 客户端的IP地址。
$remote_port 客户端的端口。
$remote_user 已经通过Auth Basic Module验证的用户名。
$request_filename 当前链接请求的文件路径,由root或alias指令与URI请求生成。
$request_uri 这个变量等于包含一些客户端请求参数的原始URI,它没法修改,请查看$uri更改或重写URI。
$scheme 所用的协议,好比http或者是https,好比rewrite ^(.+)scheme://example.com$1 redirect;
$server_addr 服务器地址,在完成一次系统调用后能够肯定这个值,若是要绕开系统调用,则必须在listen中指定地址而且使用bind参数。
$server_name 服务器名称。
$server_port 请求到达服务器的端口号。
$server_protocol 请求使用的协议,一般是HTTP/1.0或HTTP/1.1。
$uri 请求中的当前URI(不带请求参数,参数位于args),不一样于浏览器传递的args,不一样于浏览器传递的request_uri的值,它能够经过内部重定向,或者使用index指令进行修改。不包括协议和主机名,例如/foo/bar.html
相关文章
相关标签/搜索