Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
nginx+lua ÈëÃÅ
 
×÷Õߣº SRE
  2812  次浏览      29
 2019-10-17
 
±à¼­ÍƼö:
ÎÄÕ¼òµ¥µÄ˵Ã÷Nginx °²×°ºÍͨ¹ýС¹¦ÄÜ´óÌåÉÏÁ˽âÁËÔõÑù±àд nginx+lua Ä£¿éÒÔ¼°nginxµÄÅäÖÃ
±¾ÎÄÀ´×ÔÓÚ΢ÐŹ«ÖÚºÅСÃ×ÔÆ¼¼Êõ£¬ÓÉ»ðÁú¹ûÈí¼þç÷ç÷±à¼­ÍƼö

nginx+lua ±àÒë°²×°

1. nginx °æ±¾µÄÑ¡Ôñ

ÎÒÃÇÑ¡Ôñ×îРStable °æ±¾µÄ nginx-1.14.0£º

# wget https://nginx.org/download/nginx-1.14.0.tar.gz
# tar xvf nginx-1.14.0.tar.gz

2. ±àÒë nginx ÐèÒª½â¾öǰÖõÄһЩÒÀÀµ£¬ÒòΪÎÒÃÇʹÓõÄÊÇ centos ϵͳ£¬ÓÐһЩÒÀÀµ¿ÉÒÔÖ±½ÓʹÓà yum °²×°£¬µ«ÊÇÓÐһЩÎÒÃÇÏ£ÍûʹÓÃÌØ¶¨µÄ°æ±¾£¬²»ÏëʹÓÃϵͳ×Ô´øµÄ°æ±¾£¬±ÈÈç OpenSSL¡£

yum °²×°ÐèÒªµÄÒÀÀµ

yum install gcc pcre pcre-devel gd-devel xz -y

ÏÂÔØÐèÒªµÄ OpenSSL£¬ÏÖÔÚ OpenSSL ×îеÄÎȶ¨°æÊÇ 1.1.0 ϵÁУ¬1.0.2 Êdz¤ÆÚÖ§³Ö°æ±¾²¢ÇÒÖ§³Öµ½ 2019 Äê 12 Ô 31 ºÅ¡£0.9.8¡¢1.0.0 ºÍ 1.0.1 °æ±¾ÏÖÔÚÒѾ­²»ÔÙά»¤£¬¹Ù·½½¨Ò鲻ҪʹÓÃÕâЩ°æ±¾¡£

# cd nginx-1.14.0/src
# wget https://www.openssl.org/source/openssl-1.1.0h.tar.gz
# tar xvf openssl-1.1.0h.tar.gz

ÏÂÔØ Nginx Development Kit (NDK) Ä£¿é£¬lua-nginx-module ÒÀÀµ¸ÃÄ£¿é

# cd src
# git clone https://github.com/simplresty/ngx_devel_kit.git

ÏÂÔØ headers-more-nginx-module Ä£¿é

# git clone https://github.com/openresty/headers-more -nginx-module.git

ÏÂÔØ ngx_cache_purge Ä£¿é

# git clone https://github.com/FRiCKLE/ngx_cache_purge.git

ÏÂÔØ lua Ö§³ÖÄ£¿é lua-nginx-module£¬¸ÃÄ£¿éµÄÒÀÀµÏêϸ½éÉÜÇë¼û github

# git clone https://github.com/simplresty/ngx_devel_kit.git

3. ±àÒë°²×° Lua-JIT£¬ÏÖÔÚ Lua-JIT µÄ×îа汾Ϊ 2.1.0-beta3£¬ÓÚ 2017 Äê 5 Ô 1 ºÅ·¢²¼£¬ÎÒÃǾÍʹÓÃÕâ¸ö°æ±¾£º

# wget http://luajit.org/download/LuaJIT-2.1.0-beta3.tar.gz
# tar xvf LuaJIT-2.1.0-beta3.tar.gz
# mv LuaJIT-2.1.0-beta3 LuaJIT-2.1
# cd LuaJIT-2.1# make -j 10
# make install
# cd /usr/local/bin && ln -sf luajit-2.1.0-beta3 luajit
# sed -ri '/export.*LUAJIT_(LIB|INC)/d' /etc/profile
# echo -e "\nexport LUAJIT_LIB=/usr/local/lib\n \
export LUAJIT_INC=/usr/local/include/luajit-2.1\n \
export LD_LIBRARY_PATH=\$LUAJIT_LIB:\$LD_LIBRARY_PATH" >> /etc/profile
# . /etc/profile

4. ±àÒë°²×° nginx£¬ÓÉÓÚÎÒÃÇʹÓõÄÊÇ 24core ·þÎñÆ÷£¬ËùÒÔÔÚ±àÒë nginx µÄʱºòÎÒÃÇʹÓÃÁ˲¢ÐбàÒ룬ËÙ¶È»á¿ìһЩ£º

# cd nginx-1.14.0
# ./configure --prefix=/home/work/app/nginx \
--with-http_realip_module \
--with-http_gzip_static_module \
--with-http_addition_module \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_sub_module \
--without-mail_smtp_module \
--without-mail_imap_module \
--with-http_image_filter_module \
--without-mail_pop3_module \
--with-pcre=./src/pcre-8.42 \
--add-module=./src/ngx_devel_kit \
--add-module=./src/ngx_cache_purge \
--add-module=./src/headers-more-nginx-module \
--add-module=./src/lua-nginx-module \--with-pcre-jit \
--with-openssl=./src/openssl-1.1.0h \
--with-openssl-opt='-O3 -fPIC'
# make -j 20
# make install

±àÒë°²×°Íê³Éºó¿ÉÒÔ¿´µ½ÔÚ /home/work/app/nginx ÒѾ­ÓÐÁËÎÒÃÇµÄ nginx Ïà¹ØµÄÎļþ£º

# ls /home/work/app/nginx
conf html logs sbin

°²×°ÐèÒªµÄ lua Ä£¿é

ÓÉÓÚÕâÀïÎÒÃÇµÄ nginx Ö»ÊÇÒ»¸ö¾²Ì¬Îļþ·þÎñÆ÷£¬Ã»Óкó¶Ë server µÄ´¦ÀíÂß¼­£¬ÎªÁËʵÏÖÅжÏÓû§µÄ¹éÊô£¬ÎÒÃÇÐèҪͨ¹ý nginx À´ÊµÏÖ¡£¿¼Âǵ½Ê¹Óà GEOIP ¿âºóÐøÉý¼¶Î¬»¤¿ÉÄܱȽÏÂé·³£¬ÎÒÃÇʹÓõÄÊÇÄÜͨ¹ý API À´»ñÈ¡Óû§¹éÊôµÄ·þÎñ¡£

Ê×ÏÈ£¬ÎÒÃÇÊÖÍ·ÓÐÕâÑùµÄ·þÎñ£¬Í¨¹ý·ÃÎÊ¿ÉÒÔ·µ»ØÒÔÏÂʾÀý£º

# curl "http://xxx.xxxxx.com/api/v1/ip/ xx.xxx.xx.xx2/query"
{
country: "Öйú", //¹ú¼Ò
province:"±±¾©", //Ê¡·Ý
city: "±±¾©", //³ÇÊÐ
district: "º£µíÇø", //ÇøÏØ
isp: "ÁªÍ¨", //ÔËÓªÉÌ
srcip: "xx.xxx.xx.xx2" //²éѯIP

}

´ÓÉÏÃæ¿ÉÒÔ¿´³öÎÒÃÇ¿ÉÒÔ»ñÈ¡ÎÒÃÇÐèÒªµÄ¹ú¼ÒÐÅÏ¢ÁË£¬ÆäÓàÐÅÏ¢¿ÉÒÔÏȲ»¹Ü£¬±Ï¾¹ÎÒÃÇÒª×öµÄÊǹú¼ÒÁ£¶È¡£Õý³£µÄ·µ»Ø½á¹ûÊÇÒ»¸ö json ´®£¬ÄÇôÎÒÃÇÑ¡ÔñʹÓà lua-cjson À´½âÎö¸Ã json ´®£¬ÒªÔÚ nginx Öз¢Æð http ÇëÇó£¬ÎÒÃÇÑ¡ÔñʹÓà luasocket À´ÊµÏÖ¡£

1. °²×°±àÒë lua Ä£¿éÐèÒªµÄÒÀÀµ

# yum install lua-devel

2. °²×° luasocket

# cd /tmp
# wget http://files.luaforge.net/releases/ luasocket/\
luasocket/luasocket-2.0.2/luasocket-2.0.2.tar.gz
# tar xvf luasocket-2.0.2.tar.gz
# cd luasocket-2.0.2
# make && make install

3. °²×° cjson

# cd /tmp && wget https://www.kyne.com.au/~mark/\
software/download/lua-cjson-2.1.0.tar.gz
# tar xvf lua-cjson-2.1.0.tar.gz
# cd lua-cjson-2.1.0
# make && make install
# cp /usr/local/lib/lua/5.1/cjson.so /usr/lib64/lua/5.1/

4. ÑéÖ¤°²×°

ÄÜÕý³£·¢ÆðÇëÇó±íʾ luasocket °²×°³É¹¦

# lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> http = require("socket.http")
> url='http://iplib.pt.xiaomi.com/api/v1/ip/61.148. 40.192/single/query'
> result, statuscode, content = http.request(url)
> print(result)
{
"country": "Öйú",
"province": "±±¾©",
"city": "±±¾©",
"district": "º£µíÇø",
"isp": "ÁªÍ¨",
"srcip": "61.148.40.192"
}
> print(statuscode)
200

ÄÜÕý³£½âÎö json ´®£¬±íʾ cjson °²×°³É¹¦

# lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> jsoncontent='{"name":"xiaomi","age":8}'
> cjson = require("cjson")
> tb = cjson.decode(jsoncontent)
> print(tb.name)
xiaomi
> print(tb.age)
8

nginx lua ´¦ÀíÔ­Àí½éÉÜ

»ùÓÚ nginx ʹÓõĶàÄ£¿éÉè¼ÆË¼Ï룬nginx ¶Ô http ÇëÇóµÄ´¦Àí»®·ÖΪ 11 ¸ö½×¶Î¡£ÕâÑù¿ÉÒÔʹһ¸ö http ÇëÇóµÄ´¦Àí¹ý³ÌÓɺܶàÄ£¿é²ÎÓë´¦Àí£¬Ã¿¸öÄ£¿éֻרעÓÚÒ»¸ö¶ÀÁ¢¶ø¼òµ¥µÄ¹¦ÄÜ´¦Àí£¬¿ÉÒÔÓµÓиüºÃµÄÀ©Õ¹¡£11 ¸ö½×¶ÎÈçÏÂËùʾ£º

typedef enum {
NGX_HTTP_POST_READ_PHASE = 0,
NGX_HTTP_SERVER_REWRITE_PHASE,
NGX_HTTP_FIND_CONFIG_PHASE,
NGX_HTTP_REWRITE_PHASE,
NGX_HTTP_POST_REWRITE_PHASE,
NGX_HTTP_PREACCESS_PHASE,
NGX_HTTP_ACCESS_PHASE,
NGX_HTTP_POST_ACCESS_PHASE,
NGX_HTTP_TRY_FILES_PHASE,
NGX_HTTP_CONTENT_PHASE,
NGX_HTTP_LOG_PHASE
} ngx_http_phases;

Õâ 11 ¸ö½×¶ÎµÄÒâÒå·Ö±ðÈçÏ£º

NGX_HTTP_POST_READ_PHASE£º½ÓÊÕÍêÇëÇóÍ·Ö®ºóµÄ´¦Àí½×¶Î£¬ËüλÓÚ uri ÖØÐ´Ö®Ç°£¬Ò»°ãºÜÉÙÓÐÄ£¿é×¢²áÔڸý׶Σ»

NGX_HTTP_SERVER_REWRITE_PHASE£ºserver ¼¶±ðµÄ URL ÖØÐ´£¬ÔÚ location ¿é֮ǰ£»

NGX_HTTP_FIND_CONFIG_PHASE£º¸ù¾ÝÇëÇóµÄ URI ѰÕÒÆ¥ÅäµÄ location ±í´ïʽ£¬Õâ¸ö½×¶ÎÖ»ÄÜÓÉngx_http_core_moduleÄ£¿éʵÏÖ£»

NGX_HTTP_REWRITE_PHASE£º location ¼¶±ðµÄ uri ÖØÐ´½×¶Î£¬¸Ã½×¶ÎÖ´ÐÐ location »ù±¾µÄÖØÐ´Ö¸Á¿ÉÄܻᱻִÐжà´Î£»

NGX_HTTP_POST_REWRITE_PHASE£ºÖØÐ´ URL ºó£¬·ÀÖ¹´íÎóµÄ nginx.conf ÅäÖõ¼ÖÂËÀÑ­»·£¨µÝ¹éÐÞ¸Ä URI£©£¬²¢¸ù¾Ý½á¹ûÌøµ½ºÏÊʵĽ׶Σ»

NGX_HTTP_PREACCESS_PHASE£º·ÃÎÊȨÏÞ¿ØÖƵÄǰһ½×¶Î£¬¸Ã½×¶ÎÔÚȨÏÞ¿ØÖƽ׶Î֮ǰ£¬Ò»°ãÒ²ÓÃÓÚ·ÃÎÊ¿ØÖÆ£¬±ÈÈçÏÞÖÆ·ÃÎÊÆµÂÊ£¬Á´½ÓÊýµÈ£»

NGX_HTTP_ACCESS_PHASE£º·ÃÎÊȨÏÞ¿ØÖƽ׶Σ¬±ÈÈç»ùÓÚ ip ºÚ°×Ãûµ¥µÄȨÏÞ¿ØÖÆ£¬»ùÓÚÓû§ÃûÃÜÂëµÄȨÏÞ¿ØÖƵȣ»

NGX_HTTP_POST_ACCESS_PHASE£º·ÃÎÊȨÏÞ¿ØÖƵĺóÒ»½×¶Î£¬ÓÃÓÚÉÏÒ»½×¶ÎµÄÊÕβ¹¤×÷£»

NGX_HTTP_TRY_FILES_PHASE£º¸Ã½×¶ÎÊÇΪ try_files ÉèÖõģ»

NGX_HTTP_CONTENT_PHASE£ºÄÚÈÝÉú³É½×¶Î£¬¸Ã½×¶Î²úÉúÏìÓ¦£¬²¢·¢Ë͵½¿Í»§¶Ë£»

NGX_HTTP_LOG_PHASE£ºÈÕ־дÈë½×¶Î¡£ngx_http_log_module ʵ¼ÊÉÏÒ²ÊÇÔÚÕâÀï×¢²áÁËÒ»¸ö handler ʵÏÖÈÕ־дÈëµÄ¡£

Lua ¿ÉʹÓõÄÖ÷Òª½×¶Î£º

±àд nginx lua Ä£¿é

ÖÕÓÚµ½Á˸ÃÄ£¿éÀ²£¬ÔÚ¸ÃÄ£¿éÖÐÎÒÃǽ«ÊµÏÖͨ¹ýÓû§ IP µÄ¹éÊô½«Óû§Öض¨Ïòµ½ÖÐ / Ó¢ÎÄÊ×Ò³¡£

1. Ê×Ïȹ¹Ôì»ñÈ¡Óû§µÄÕæÊµ IP£º

cjson = require("cjson")
http = require("socket.http")
local remote_ip = ngx.req.get_headers() ["x-forwarded-for"]

if remote_ip == nil
then
remote_ip = ngx.req.get_headers()["x-real-ip"]
else
local remote_ip_tmp = split(remote_ip, ',')
remote_ip = remote_ip_tmp[1]
end

if remote_ip == nil
then
remote_ip = ngx.var.remote_addr
end

ÒòΪ x-forwarded-for »ñÈ¡µÄÓû§ IP ҪôÊÇ nil£¬ÒªÃ´ÊÇ 192.168.1.100£¬ÒªÃ´ÊÇ 192.168.1.100,192.168.100.10 ÕâÖÖ¸ñʽ£¬ËùÒÔÒª½øÐд¦Àí£¬»ñÈ¡µ½Óû§×îÕæÊµµÄ IP£¬Èç¹û¸Ã×Ö¶ÎûÓÐÄÚÈÝÔòÈ¡ remote_addr ×÷ΪÓû§ IP¡£ÒòΪ lua ÖеÄ×Ö·û´®²Ù×÷ûÓÐ split º¯Êý£¬ËùÒÔÕâÀïÎÒÃÇ×Ô¼ºÊµÏÖÁË splite ²Ù×÷£º

function split( str,reps )
local resultStrList = {}
string.gsub(str,'[^'..reps..']+', function ( w )
table.insert(resultStrList,w)
end)
return resultStrList
end

2. ¹¹Ôì»ñÈ¡Óû§ IP ¹éÊôµÄ http ÇëÇó¡£ÎÒÃÇÔÚÉÏÒ»²½ÖÐÒѾ­»ñÈ¡µ½ÁËÓû§µÄÕæÊµ IP£¬ÏÖÔÚ½øÒ»²½»ñÈ¡Óû§ËùÊôµÄ¹ú¼Ò¡£

url_prefix = "http://xxx.xx.com/api/v1/ip/"
url_postfix = "/single/query"
real_url = url_prefix..remote_ip..url_postfix
result, statuscode, content = http.request(real_url)

ÏÖÔÚÎÒÃÇÒѾ­»ñÈ¡µ½Óû§ IP µÄ¹éÊôÐÅÏ¢£¬µ«ÊÇÓÉÓÚ cjson ´¦ÀíµÄ json ´®Ö»ÄÜÔÚÒ»ÐÐÖУ¬ËùÒÔÎÒÃÇÒªÉîÈë´¦ÀíÏ»ñÈ¡µ½µÄÊý¾Ý£º * È¥µô¶àÓڵĻ»ÐÐ * È¥µô¶àÓڵĿոñ

newstr = string.gsub(result, '\n', '')
newstr = string.gsub(newstr, ' ', '')

½ÓÏÂÀ´¿ÉÒÔ¶Ô´¦ÀíºóµÄ newstr ½øÐÐ cjson decode ²Ù×÷ÁË£º

tb = cjson.decode(newstr)
if tb == nil
then
ngx.redirect("/en", ngx.HTTP_MOVED_TEMPORARILY)
else
if (tb.country == "Öйú")
then
ngx.redirect("/zh", ngx.HTTP_MOVED_TEMPORARILY)
else
ngx.redirect("/en", ngx.HTTP_MOVED_TEMPORARILY)
end
end

ÔÚ´¦ÀíÉÏÎÒÃÇΪÁ˳°ôÐÔ¿¼ÂÇ£¬µ± cjson decode ʧ°Üʱ tb µÄÖµ»áÊÇ nil£¬ÔòºóÃæËùÈ¡µÄ¹ú¼ÒÊôÐÔÒ²ÊÇ nil£¬Èç¹ûÕâÖÖÇé¿ö·¢ÉúÔò·µ»ØÓ¢ÎÄÊ×Ò³£¬»¹ÓÐÒ»¸öÎÊÌ⣬Èç¹ûÎÒÃǸù±¾¾ÍûÓлñÈ¡µ½¿Í»§µÄ IP£¬ÊDz»ÊÇ¿ÉÒÔÊ¡ÂÔµôÄÚ²¿·¢Æð http ·ÃÎʵĻ·½Ú£¿Ö±½Ó·µ»ØÓ¢ÎÄÊ×Ò³£¬àÅ£¬ÏÂÃæÔÚ·¢Æð http ÇëÇóµÄ´úÂëÇ°ÃæÌí¼ÓÈçÏ´úÂ룺

if remote_ip == nil or remote_ip == ""
then
ngx.redirect("/en", ngx.HTTP_MOVED_ TEMPORARILY)end

»¹ÓÐÒ»¸öÎÊÌ⣬Èç¹ûÎÒÃÇÏòºó¶Ë·¢Æð http ÇëÇóºó£¬ÇëÇó±» block ÁË£¬µÈÁË 1 ·ÖÖӲŷµ»ØÔõô°ì£¿ÕâÑùµÄ»°ÎÒÃǵÄÒ³ÃæÆñ²»ÊÇÒ²»áÓÐÎÊÌ⣿µÈÒ»·ÖÖÓÔÙ·µ»Ø¸øÓû§£¿Õâ¸öÌ«²»ÓÅÑÅÁË£¬ÎÒÃÇÕâÀï¿ÉÒÔ¸øÇëÇóÉèÖó¬Ê±Ê±¼ä£¬±ÈÈ糬¹ý 1s ÖоÍÇ¿ÖÆ½áÊø£¬ËùÒÔÎÒÃǹ¹Ôì http ÇëÇóµÄ´úÂë±ä³ÉÁËÕâÑù£º

http = require("socket.http")
http.TIMEOUT = 1

×îºóÒ»¸öÐèÇó£¬Ôõô¿´ÎÒÃÇдµÄ½Å±¾ÓÐûÓÐÖ´Ðгɹ¦ÄØ£¿ÔõôÅжÏÎÒÃÇͨ¹ýÓû§ IP »ñÈ¡µ½µÄ¹ú¼ÒÊÇ·ñÕýÈ·ÄØ£¿ÎÒÃÇÐèÒª¼Ó´òӡһЩÈÕÖ¾ÐÅÏ¢£¬ÎÒÃÇÔÚif (tb.country == "Öйú")Ç°ÃæÌí¼ÓÁËÈçÏ´úÂ룺

ngx.log(ngx.ERR, "reqeustInfo : remote_ip:", \
remote_ip, ",country:", tb.country)

ÕâÑùÎÒÃǾÍÄÜÖªµÀ»ñÈ¡µ½µÄÓû§ÊÇÀ´×ÔÓÚÄÄÀïÁË¡£ ÖйúÓû§·ÃÎÊÎÒÃǵIJâÊÔÓòÃû xxxx.srv »á±»Öض¨Ïòµ½ xxxx.srv/zh Ò³Ãæ£¬¹úÍâ IP ·ÃÎÊ»á±»ÖØ¶¨Ïòµ½ xxxx.srv/en Ò³Ãæ£¬ÈÕ־ʾÀýÈçÏ£º

2018/05/28 18:28:22 [error] 27267#0: *46639625 [lua] docs.lua:75:
reqeustInfo : remote_ip:xx.xxx.xxx.179,
country:Ó¡¶È, client: xx.xxx.xxx.179,
server: docs-tst.srv,
request: "GET / HTTP/1.1", host: "docs-tst.srv"

-

2018/05/28 18:30:33 [error] 27267#0: *46640486 [lua] docs.lua:75:
reqeustInfo : remote_ip:111.xx.xxx.196,
country:Öйú, client: 111.xx.xx.196,
server: docs-tst.srv, request: "GET / HTTP/1.1", host: "docs-tst.srv"

×îºó nginx ÅäÖÃÈçÏ£º

location / {
rewrite_by_lua_file lua/docs.lua;
}

location /zh {
alias docs-zh/;
autoindex on;
autoindex_localtime on;
expires 24h;
}

location /en {
alias docs-en/;
autoindex on;
autoindex_localtime on;
expires 24h;
}
   
2812 ´Îä¯ÀÀ       29
????

HTTP????
nginx??????
SD-WAN???
5G?????
 
????

??????????
IPv6???????
??????????
???????
????

????????
????????
???????????????
??????????