nginx 에 lua 스 크 립 트 통합: 사용자 정의 Http 헤드 추가, IP 차단 등
강제 검색엔진 은 mixlr. com 만 색인 합 니 다.
Google 은 하위 도 메 인 이름 을 완전히 독립 된 사이트 로 간주 합 니 다. 우 리 는 파충류 가 하위 도 메 인 이름 의 페이지 를 잡 아 페이지 rank 을 낮 추 는 것 을 원 하지 않 습 니 다.
location /{
header_filter_by_lua '
if ngx.var.query_string and ngx.re.match( ngx.var.query_string, "^([0-9]{10})$" ) then
ngx.header["Expires"] = ngx.http_time( ngx.time() + 31536000 );
ngx.header["Cache-Control"] = "max-age=31536000";
end
';
robots. txt 에 대한 요청 이 mixlr. com 도 메 인 이 아니라면 내부 에 robots 로 다시 쓰기diallow. txt, 표준 재 작성 명령 도 이 수 요 를 실현 할 수 있 지만 Lua 의 실현 은 더욱 쉽게 이해 하고 유지 할 수 있 습 니 다.
프로그램 논리 에 따라 응답 헤드 설정
Lua 는 Nginx 기본 설정 규칙 보다 유연 한 설정 방식 을 제공 합 니 다.아래 의 예 에서 저 희 는 응답 헤드 를 정확하게 설정 해 야 합 니 다. 그러면 브 라 우 저가 지정 한 요청 헤드 를 보 낸 후에 무기한 캐 시 정적 파일 을 사용 할 수 있 습 니 다. 예, 사용 자 는 한 번 만 다운로드 하면 됩 니 다.이 재 작성 규칙 은 모든 정적 파일 을 만 듭 니 다. 요청 한 매개 변수 에 시간 스탬프 값 이 포함 되 어 있 으 면 Expires 와 Cache - Control 응답 헤드 를 설정 합 니 다.
location /{
header_filter_by_lua '
if ngx.var.query_string and ngx.re.match( ngx.var.query_string, "^([0-9]{10})$" ) then
ngx.header["Expires"] = ngx.http_time( ngx.time() + 31536000 );
ngx.header["Cache-Control"] = "max-age=31536000";
end
';
try_files $uri @dynamic;}
jQuery JSONP 에서 요청 한 타임 스탬프 인자 삭제
많은 외부 클 라 이언 트 가 JSONP 인 터 페 이 스 를 요청 할 때 타임 스탬프 와 유사 한 인 자 를 포함 하여 Nginx proxy 캐 시 를 명중 시 킬 수 없습니다 (지정 한 HTTP 인 자 를 무시 할 수 없 기 때 문 입 니 다).다음 규칙 은 시간 스탬프 인 자 를 삭제 하여 Nginx 가 upstream server 의 응답 내용 을 캐 시 하여 백 엔 드 서버 의 부 하 를 줄 일 수 있 도록 합 니 다.
location /{
rewrite_by_lua '
if ngx.var.args ~= nil then
-- /some_request?_=1346491660 becomes /some_request
local fixed_args, count = ngx.re.sub( ngx.var.args, "&?_=[0-9]+", "" );
if count > 0 then
return ngx.exec(ngx.var.uri, fixed_args);
end
end
';}
백 엔 드 의 느 린 요청 로 그 를 Nginx 의 오류 로그 에 기록 합 니 다.
백 엔 드 요청 응답 이 느 리 면 추가 추적 을 위해 Nginx 의 오류 로그 에 기록 할 수 있 습 니 다.
location /{
log_by_lua '
if tonumber(ngx.var.upstream_response_time) >= 1 then
ngx.log(ngx.WARN, "[SLOW] Ngx upstream response time: " .. ngx.var.upstream_response_time .. "s from " .. ngx.var.upstream_addr);
end
';}
Redis 기반 실시 간 IP 차단
어떤 경우 에는 불량배 파충류 의 포획 을 막 아야 한다. 이 는 전문 적 인 봉쇄 장 치 를 통 해 할 수 있 지만 루 아 를 통 해 간단 한 버 전의 봉쇄 를 실현 할 수 있다.
lua_shared_dict banned_ips 1m;
location /{
access_by_lua '
local banned_ips = ngx.shared.banned_ips;
local updated_at = banned_ips:get("updated_at");
-- only update banned_ips from Redis once every ten seconds:
if updated_at == nil or updated_at < ( ngx.now() - 10 ) then
local redis = require "resty.redis";
local red = redis:new();
red:set_timeout(200);
local ok, err = red:connect("your-redis-hostname", 6379);
if not ok then
ngx.log(ngx.WARN, "Redis connection error retrieving banned_ips: " .. err);
else
local updated_banned_ips, err = red:smembers("banned_ips");
if err then
ngx.log(ngx.WARN, "Redis read error retrieving banned_ips: " .. err);
else
-- replace the locally stored banned_ips with the updated values:
banned_ips:flush_all();
for index, banned_ip in ipairs(updated_banned_ips) do
banned_ips:set(banned_ip, true);
end
banned_ips:set("updated_at", ngx.now());
end
end
end
if banned_ips:get(ngx.var.remote_addr) then
ngx.log(ngx.WARN, "Banned IP detected and refused access: " .. ngx.var.remote_addr);
return ngx.exit(ngx.HTTP_FORBIDDEN);
end
';}
현재 특정 IP 의 접근 을 막 을 수 있 습 니 다.
ruby> $redis.sadd("banned_ips","200.1.35.4")
Nginx 프로 세 스 는 10 초 마다 Redis 에서 최신 금지 IP 명단 을 가 져 옵 니 다.주의해 야 할 것 은 구조 에 Haproxy 와 같은 부하 균형 서버 를 사용 했다 면 $remoteaddr 는 정확 한 원 격 IP 주소 로 설정 합 니 다.
이 방법 은 HTTP User - agent 필드 의 검사 에 도 사용 할 수 있 으 며 지정 한 조건 을 만족 시 켜 야 합 니 다.
Nginx 출력 CSRF 사용 (form authenticity token)
Mixlr 는 페이지 캐 시 를 대량으로 사용 합 니 다. 이 를 통 해 각 페이지 에 세 션 단계 의 CSRF token 을 어떻게 출력 하 느 냐 가 문제 입 니 다.우 리 는 Nginx 의 하위 요청 을 통 해 upstream 웹 server 에서 token 을 가 져 온 다음 Nginx 의 SSI (server - side include) 기능 을 이용 하여 페이지 에 출력 합 니 다.이렇게 하면 CSRF 공격 문 제 를 해결 할 뿐만 아니 라 cache 가 정상적으로 이 용 될 수 있 도록 보장 한다.
location /csrf_token_endpoint {internal;
include /opt/nginx/conf/proxy.conf;
proxy_pass "http://upstream";}
location @dynamic{
ssi on;set $csrf_token '';
rewrite_by_lua '
-- Using a subrequest, we our upstream servers for the CSRF token for this session:
local csrf_capture = ngx.location.capture("/csrf_token_endpoint");
if csrf_capture.status == 200 then
ngx.var.csrf_token = csrf_capture.body;
-- if this is a new session, ensure it sticks by passing through the new session_id
-- to both the subsequent upstream request, and the response:
if not ngx.var.cookie_session then
local match = ngx.re.match(csrf_capture.header["Set-Cookie"], "session=([a-zA-Z0-9_+=/+]+);");
if match then
ngx.req.set_header("Cookie", "session=" .. match[1]);
ngx.header["Set-Cookie"] = csrf_capture.header["Set-Cookie"];
end
end
else
ngx.log(ngx.WARN, "No CSRF token returned from upstream, ignoring.");
end
';
try_files /maintenance.html /rails_cache$uri @thin;}
CSRF 토 큰 생 성 app / metal / csrftoken_endpoint.rb:
classCsrfTokenEndpointdefself.call(env)if env["PATH_INFO"]=~/^\/csrf_token_endpoint/
session = env["rack.session"]||{}
token = session[:_csrf_token]if token.nil?
token =SecureRandom.base64(32)
session[:_csrf_token]= token
end[200,{"Content-Type"=>"text/plain"},[ token ]]else[404,{"Content-Type"=>"text/html"},["Not Found"]]end
endend
우리 의 모드 파일 예제:
<metaname=”csrf-param”value=”authenticity_token”/>
<meta name=”csrf-token” value=”<!–# echo var=”csrf_token” default=”” encoding=”none” –>”/>
Again you could make use of lua_shared_dict to store in memory the CSRF token for a particular session. This minimises the number of trips made to /csrf_token_endpoint.
원본 링크:http://devblog.mixlr.com/2012/09/01/nginx-lua/
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.