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

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

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

一、指定 IP

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
[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
[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
[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

二、多判斷式

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
[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
[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
[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

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