X-forwarded-for 헤더를 기반으로 리소스에 대한 액세스를 거부하는 방법


13

X-forwarded-for 헤더에 전달 된 클라이언트 IP를 기반으로 Nginx 뒤의 리소스에 대한 액세스를 제한하려고합니다. Nginx가 Google Cloud Platform의 Kubernetes Cluster에있는 컨테이너에서 실행되고 실제 클라이언트 IP는 x-forwarded-for 헤더로만 전달됩니다.

지금까지 다음 코드를 사용하여 단일 IP에 대해 관리했습니다.

set $allow false;
if ($http_x_forwarded_for ~* 123.233.233.123) {
    set $allow true;
}
if ($http_x_forward_for ~* 10.20.30.40) {
    set $allow false;
}
if ($allow = false) {
    return 403;
}

그러나 모든 범위의 IP에 대해 어떻게 할 수 있습니까? 수백 개의 IP를 직접 지정하는 것은 의미가 없습니다.

모든 도움에 감사드립니다

답변:


11

RealIP 모듈을 사용하여 X-Forwarded-For헤더 값을 준수하십시오 . 설정 set_real_ip_from리버스 프록시 (의 현재 값의 IP 주소 $remote_addr).

예를 들면 다음과 같습니다.

server {
    ...
    real_ip_header X-Forwarded-For;
    set_real_ip_from 10.1.2.3;
    ...
}

이제 클라이언트의 실제 IP 주소를 사용하여 $remote_addrallow/ deny지시문 을 사용할 수 있습니다 . 자세한 내용은 이 문서 를 참조하십시오 .


그래서 나는 다음을 시도했지만 아무리 혼란 스럽습니까? location / { real_ip_header X-Forwarded-For; set_real_ip_from 10.0.0.0/8; real_ip_recursive on; allow xxx.xxx.xxx.xxx;
p1hr

Google로드 밸런싱 문서를 확인한 후 다음을 발견했습니다 X-Forwarded-For: <unverified IP(s)>, <immediate client IP>, <global forwarding rule external IP>, <proxies running in GCP> (requests only) . <immediate client IP> 항목은로드 밸런서에 직접 연결된 클라이언트입니다.
p1hr

1
이 작업을 수행하려면, 당신의 주소 범위를 확인해야 <global forwarding rule external IP>하고 <proxies running in GCP>추가합니다 set_real_ip_from그들 모두를 커버하는 문을.
Richard Smith

<global forwarding rule external IP>내 서비스의 외부 IP이며 GCP에는 다른 프록시가 없습니다. 내 nginx 로그 [31/Jul/2017:20:05:46 +0000] "GET / HTTP/1.1" 403 169 "-" "curl/7.54.0" "aaa.aaa.aaa.aaa, bbb.bbb.bbb.bbb, ccc.ccc.ccc.ccc"에는 ccc.ccc.ccc.ccc가 전역 전달 규칙 인 bbb.bbb.bbb.bbb가 바로 다음 형식으로 요청을 봅니다. ip-whatsmyip.org에서 보는 것과 일치합니다. 그 부분을 추출하는 방법을 조언 할 수 있습니까?
p1hr

1
좋아, 이제 혼란스러워지고있다. 당신은 필요 set_real_ip_from하면 허용 할 하나의 오른쪽에있는 모든 주소에 대한 / 거부합니다. real_ip_recursive섹션에 표시된대로 .
Richard Smith

5

Richard의 답변에는 이미 실제 IP 주소를 nginx에 가장 잘 얻는 방법에 대한 정보가 포함되어 있습니다.

한편 IP 범위 지정에 관한 문제는 http://nginx.org/en/docs/http/ngx_http_geo_module.html 을 사용할 수 있습니다 .

geo같은 모듈 일 map모듈, 즉, 변수는 IP 어드레스의 값에 따라 값이 할당 얻는다.

예를 들면 :

geo $allow {
    default 0;
    192.168.168.0/24 1;
}

server {
    real_ip_header X-Forwarded-For;
    set_real_ip_from 10.1.2.3;

    if ($allow = 0) {
        return 403;
    }
}

여기서 우리 geo는 기본값 $allow이 0 인 맵 을 할당합니다 . IP 주소가 서브넷 192.168.168.0/24$allow있으면 값 1을 얻고 요청이 허용됩니다.

geoIP 범위를 정의하는 데 필요한 만큼 많은 행을 블록 에 가질 수 있습니다 .


감사합니다! 그것은 실제로 잘 작동하는 것처럼 보입니다. 마지막으로 직면 한 한 가지는 X 전달에서 client_ip입니다. 현재 마지막으로 전달 된 3 개의 IP 주소가 사용됩니다. real_ip_recursive on;아래에 추가 set_real_ip_from했지만 아무런 차이가 없습니다
p1hr

X-Forwarded-For헤더에 세 개의 개별 주소가 있다는 의미 입니까, 즉 요청이 여러 프록시를 통해 제공됩니까? 클라이언트 IP 만 포함 할 수있는 다른 헤더가 있습니까?
Tero Kilkanen

체인의 모든 프록시는 IP 주소를 X-Forwarded-For헤더에 추가합니다 . 추가 외에도 프록시 체인의 신뢰할 수있는 각 서버 IP 주소에 대한 지시문 real_ip_recursive on을 추가해야합니다 set_real_ip_from. 그런 다음 Nginx는 이러한 각 지시문을 처리하여 클라이언트 IP를 X-Forwarded-For지정된 set_real_ip_from값 과 일치하지 않는 헤더 에서 첫 번째 값으로 반환 합니다.
miknik

FWIW,이 조합은 AWS ALB에서 작동하지 않았습니다. 작업 set_real_ip와 동일한 IP로, 지리 블록 내부의 프록시 지시어를 사용했다 무슨 짓을 - nginx.org/en/docs/http/ngx_http_geo_module.html
talonx

3

이것들이 나를 위해 일했습니다.

geo $remote_addr $giveaccess {
      proxy 172.0.0.0/8; <-- Private IP range here
      default 0;
      11.22.33.44 1; <-- Allowed IP here
    }


server{
##
    location ^~ /secure_url_here {
        if ($giveaccess = 0){
          return 403; 
        }
        try_files $uri $uri/ /index.php?$args; <-- Add this line specific for your CMS, if required.
    }

참조 : http://nginx.org/en/docs/http/ngx_http_geo_module.html

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.