어떻게 2 층 서버 의 2 층 Nginx 에서 사용자 IP 를 가 져 옵 니까?
1. 이전에 nginx 의 서버 설정 을 할 때 문제 가 발생 했 습 니 다. 그 전에 서버 는 클 라 이언 트 의 최대 동시 연결 을 제한 하 는 기능 이 있 었 고 이 기능 의 실현 은 서버 에서 하 는 것 입 니 다.
$remote-addr
이런 설정 으로 이 루어 졌 습 니 다.그러나 전단 1 층 (부하, CDN, 방화벽, 보안 서비스) 서버 를 추가 한 후 받 은 클 라 이언 트 IP 는 실제 사용자 IP 주소 가 아 닌 전단 서버 의 IP 로 바 뀌 었 다.
2. 이런 문제 에서 저 는 nginx 홈 페이지 의 소 개 를 몇 번 다시 봤 는데 그 중에서 또 다른 중요 한 변 수 를 발 견 했 습 니 다.
$proxy_add_x_forwarded_for
이 변 수 는 클 라 이언 트 접근 요청 의 X - forward - for 필드 의 값 입 니 다. 요청 에 이 필드 가 포함 되 어 있 지 않 으 면 이 변 수 를 자동 으로 사용 하면 reote - addr 라 는 변수 와 같 습 니 다.이것 은 HTTP 요청 에서 일반적인 상황 에서 전단 서버 에 저 장 된 클 라 이언 트 의 실제 IP 주소 필드 를 가 져 올 수 있 습 니 다. 보통 우리 가 말 하 는 X 입 니 다.FORWARDED_FOR 필드, 그리고 이런 방법 을 통 해 우 리 는 다양한 기능 을 실현 할 수 있 습 니 다.
3. 다음은 제 가 실제 적 으로 여러분 께 간단 한 시범 을 보 여 드 리 겠 습 니 다.부족 한 점 이 많 으 니 지적 해 주시 기 바 랍 니 다.
먼저 우 리 는 Nginx 의 환경 을 구축 합 니 다. 여기 서 우 리 는 1.7 시리즈 의 최신 버 전 1.7.9 를 예 로 들 면 (버 전에 관 한 문 제 는 FAQ 1 참조)
다운로드, WGET 에 필요 한 주소http://nginx.org/download/nginx-1.7.9.tar.gz
1. Nginx 다운로드
[lugt@localhostmysql]$ wget http://nginx.org/download/nginx-1.7.9.tar.gz
2. 스트레스 를 풀다
[lugt@localhostmysql]$ tar zxvf nginx-1.7.9.tar.gz
3. 직접 컴 파일 (openssl 등 플러그 인 지원 이 필요 한 지 고려 해 야 합 니 다)
[lugt@localhost mysql]$cd nginx-1.7.9
[lugt@localhost nginx-1.7.9]$ ./configure
[lugt@localhost nginx-1.7.9]$ make
[lugt@localhost nginx-1.7.9]$ su
[[email protected]]$ make install
4. 그리고 nginx. conf 프로필 을 수정 합 니 다.
[lugt@localhost nginx-1.7.9]$ su
[lugt@localhost nginx-1.7.9]$cd /usr/local/nginx
[lugt@localhostnginx]$ vi conf/nginx.conf
그리고 nginx. conf 에서 이곳 을 찾 아 부하 균형 을 설정 하고 CDN 을 모방 합 니 다.
upstream dnsnginx1 {
server[*.*.*.*/yourhostname]:8080 weight=10000; # IP、
}
server {
listen 80;
server_name
#access_log logs/host.access.log main
location /{
proxy_pass http://dnsnginx1;
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 HTTP_X_FORWARDED_FOR $remote_addr;
proxy_redirect default;
}
}
가상 서버 를 8080 포트 에 설정 합 니 다.
limit_conn_zone $proxy_add_x_forwarded_for zone=addr:10m; # 10M
server {
listen 8080;
server_name [*.*.*.*/yourhostname]:8080 weight=10000; # IP、
limit_conn addr 1; # 1
location / {
root html;
index index.html index.htm;
}
}
보존이어서 프로필 문법 테스트
[lugt@localhostnginx]$ ./sbin/nginx –t
시작 서버
[lugt@localhostnginx]$ ./sbin/nginx
4. ab 도 구 를 사용 하여 효 과 를 봅 니 다.
[lugt@localhost nginx]$ ab –c 10 –n 100 –v 4 http://127.0.0.1/ | grep HTTP/1.1
이 줄 의 뜻: AB 테스트 도 구 를 통 해 주 소 를 방문 하고 동시 연결 수 는 30 이 며 총 300 회 테스트 하여 HTTP 반환 헤더 정 보 를 표시 합 니 다.
ab 도 구 를 통 해 몇 개의 연결 을 동시에 보 내 든 200 을 성공 적 으로 되 돌려 주 는 것 은 nginx 의 최대 병렬 연결 수 를 제한 하 는 것 이 므 로 IP 에 대한 제한 기능 이 이미 사용 할 수 있 음 을 증명 할 수 있 습 니 다.참고 자료 FAQ 2 참조
질문
현재 사용 중인 Nginx 버 전이 1.7.1 버 전에 미 치지 못 하면 nginx 가 이 기능 을 지원 하지 않 을 수 있 습 니 다.
이 럴 때 는 코드 를 통 해 limit 에 끼 워 야 합 니 다.conn_handler 함수 에서 request 에서 x 가 져 오기forwarded_for 의 값.
1.6.1 버 전의 경우 코드 가 다음 과 같이 증가 합 니 다.src/http/modules/ngx_http_limit_conn.c 184 행
hash =ngx_crc32_short(key.data, key.len);
If(“” == &ctx->key){
If(NULL!= r->main->headers_in->x_forwarded_for->elts){
key.data= *(char*)r->main->headers_in->x_forwarded_for->elts;
key.len = 4;
hash =ngx_crc32_short(key.data, key.len);
} }
FAQ 2 참고 자료
참고 데이터 입 니 다. 가 져 오기
[lugt@localhost~]$ ab -c 10 -n 100 -v 4 http://127.0.0.1/ | grep HTTP/1.1
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1 200 OK
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1 200 OK
English Version
How to retrievethe true ip of the client user if there are two layers of servers
Days before, wehave been faced such a difficulty which is we can’t use the variable $remote_addr for gathering the clients’ip address. This problem surfaces when we used a proxy server between the trueserver and client, which is actually a cdn. And that makes our functions oflimiting the maximum connections a client can make to a server at a time. Thissituation can also found if the load balance or any anti-spam service are inuse. So that’s why we can’t use remote_addr variable further.
After I did someresearch on the documentation and the code , I found out that this problem canbe solved by replacing the
$remote_addr
variable with the
$proxy_add_x_forwarded_for
variable. As this variable allows to retrievethe data from the column X_forwarded_for from the request, we can use thisvariable functioning in many ways. And now I shall makean easy example to practically use this method.
First of all,build up a Nginx server.
Here, I will usethe 1.7.9 version (latest to the written time) for instance, therefore, thereexist some differences between older versions than 1.7.1 (see FAQ 1)
1. Download A Nginx Copy:
[lugt@localhostmysql]$ wget http://nginx.org/download/nginx-1.7.9.tar.gz
2. Decompress the file
[lugt@localhostmysql]$ tar zxvf nginx-1.7.9.tar.gz
3. Compile The Code
[lugt@localhostmysql]$ cd nginx-1.7.9
[[email protected]]$ ./configure
[[email protected]]$ make
[[email protected]]$ su
[[email protected]]$ make install
4. And edit the config file nginx.conf
[lugt@localhost nginx-1.7.9]$ su
[[email protected]]$ cd /usr/local/nginx
[lugt@localhostnginx]$ vi conf/nginx.conf
There add suchdirectives to the server1 for emulate for an CDN server
upstream dnsnginx1 {
server[*.*.*.*/yourhostname]:8080 weight=1000; #fill in your ip/hostname
}
server {
listen 80;
server_name [hostname] #fill your ip/ hostname here
#access_log logs/host.access.log main
location /{
proxy_pass http://dnsnginx1;
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 HTTP_X_FORWARDED_FOR $remote_addr;
proxy_redirect default;
}
}
After the end ofone server directive, and in the http directive, add so to function the sever2
limit_conn_zone $proxy_add_x_forwarded_for zone=addr:10m; # sample setting
server {
listen 8080;
server_name [*.*.*.*/hostname]:8080 weight=10000; #fill in ip/hostname here
limit_conn addr 1; # Enablethe limitation of connection per ip at a time to 1.
location / {
root html;
index index.html index.htm;
}
}
And then you cansave , test the config file and run nginx
Test your configfile:
[lugt@localhostnginx]$ ./sbin/nginx –t
Start the nginx server
[lugt@localhostnginx]$ ./sbin/nginx
Now, the serverhas been set and you can run a test at instance.
/* This CommandMeans to run a tool to connect to server as 10conn/once and 10 conns in total*/
[lugt@localhost~]$ ab -c 10 -n 100 -v 4 http://127.0.0.1/ | grep HTTP/1.1
FAQ 1
There is actuallysome little malfunctions when using elder versions than 1.7.1 (Probably the newversion has it for a new feature).So to use this directive in earlier versions,some code need to be added.
As a Example inthe version 1.6.1
In filesrc/http/modules/ngx_http_limit_conn.c Line around 184
hash =ngx_crc32_short(key.data, key.len);
If("" == &ctx->key){
If(NULL!= r->main->headers_in->x_forwarded_for->elts){
key.data= *(char*)r->main->headers_in->x_forwarded_for->elts;
key.len = 4;
hash =ngx_crc32_short(key.data, key.len);
}
}
FAQ 2 TestingResults
[lugt@localhost~]$ ab -c 10 -n 100 -v 4 http://127.0.0.1/ | grep HTTP/1.1
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1 200 OK
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1503 Service Temporarily Unavailable
HTTP/1.1 200 OK
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
간단! Certbot을 사용하여 웹 사이트를 SSL(HTTPS)화하는 방법초보자가 인프라 주위를 정돈하는 것은 매우 어렵습니다. 이번은 사이트를 간단하게 SSL화(HTTP에서 HTTPS통신)로 변경하는 방법을 소개합니다! 이번에는 소프트웨어 시스템 Nginx CentOS7 의 환경에서 S...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.