修改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
相關文章
相關標籤/搜索