如何設定 Nginx X-Forwarded-For 只允需特定IP訪問

這功能通常是用在管理者後台,讓外部用戶不能直接訪問管理者後台,必免有心人事嘗試登入。

可透過 Nginx X-Forwarded-ForHostproxy_set_header 函式,取得用戶真實IP,並加入判斷式回傳 http statu code。

一、指定 IP

[root@localhost ~]$ vim /etc/nginx/nginx.conf

server {
    listen 80;
    server_name yourdomain.com;

    proxy_headers_hash_max_size 51200;
    proxy_headers_hash_bucket_size 6400;

    # 定義 header 變數, 記錄使用者的 IP
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Scheme $scheme;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Port $server_port;

    proxy_max_temp_file_size 0;

    proxy_set_header Connection "";
    proxy_buffering off;
    proxy_request_buffering off;

    access_log  /var/log/nginx/$host-access.log  main;
    error_log   /var/log/nginx/$host-error.log;

    if ($proxy_add_x_forwarded_for !~ "192.168.1.2") {
       return 403;
    }

    location / {
       proxy_pass http://192.168.1.3:8080$uri$is_args$args;
    }
}

:wq

[root@localhost ~]$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

[root@localhost ~]$ nginx -s reload

程式說明:

  • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 取得請求 Header X-Forwarded-For 中的用户真實 IP, 並加到 $proxy_add_x_forwarded_for 變數內
  • if(...) 變數 $proxy_add_x_forwarded_for 不等於 192.168.1.2 並回覆 return 403,返回 403

二、多判斷式

[root@localhost ~]$ vim /etc/nginx/nginx.conf

server {
    listen 80;
    server_name yourdomain.com;

    proxy_headers_hash_max_size 51200;
    proxy_headers_hash_bucket_size 6400;

    # 定義 header 變數, 記錄使用者的 IP
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Scheme $scheme;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Port $server_port;

    proxy_max_temp_file_size 0;

    proxy_set_header Connection "";
    proxy_buffering off;
    proxy_request_buffering off;

    access_log  /var/log/nginx/$host-access.log  main;
    error_log   /var/log/nginx/$host-error.log;

    if ($http_host ~ "yourdomain.com") {
       set $set_block HostErr;
    }
 
    if ($proxy_add_x_forwarded_for != '192.168.1.2') {
       set $set_block "${set_block}IPErr";
    }
 
 
    if ($set_block = HostErrIPErr) {
       return 403;
       break;
    }

    location / {
       proxy_pass http://192.168.1.3:8080$uri$is_args$args;
    }
}

:wq

[root@localhost ~]$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

[root@localhost ~]$ nginx -s reload

如果都不匹配時會出現以下狀況