Centos7安裝Openresty

經過yum安裝html

在 /etc/yum.repos.d/ 下新建 OpenResty.repo 內容nginx

[openresty]
name=Official OpenResty Repository
baseurl=https://copr-be.cloud.fedoraproject.org/results/openresty/openresty/epel-$releasever-$basearch/
skip_if_unavailable=True
gpgcheck=1
gpgkey=https://copr-be.cloud.fedoraproject.org/results/openresty/openresty/pubkey.gpg
enabled=1
enabled_metadata=1

查看可用的openresty軟件git

yum --disablerepo="*" --enablerepo="openresty" list available

當前安裝的是 openresty.x86_64 版本1.11.2.2-8.el7.centos, 內置的openssl 是 1.0.2jgithub

安裝web

yum install openresty

默認會安裝到 /usr/local/openresty/ 目錄下, 目錄下包含了 luajit, lualib, nginx, openssl, pcre, zlib 這些組件redis

若是安裝時顯示Require GeoIP, 須要先安裝geoip後再安裝openresty後端

yum install epel-release
yum --enablerepo=epel install geoip

使用命令行直接啓動centos

/usr/local/openresty/nginx/sbin/nginx -c /usr/local/openresty/nginx/conf/nginx.conf

OpenResty安裝時, 已經把路徑加入了/usr/bin, 而且添加了服務 /etc/init.d/openresty, 能夠經過服務腳本啓動緩存

systemctl start/stop/status openresty

能夠經過-p參數設置工做目錄, 對應nginx的conf, html, log均可以放到這個目錄下tomcat

openresty -p /opt/my-fancy-app/

防火牆檢查和配置

# 查看狀態
systemctl status firewalld
# 查看開放的端口
firewall-cmd --zone=public --list-all
# 添加80端口
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --reload

Update 2018-07-17: 若是使用了-p參數, 將工做區間指向了其餘目錄, 那麼在配置nginx.conf時, 須要將 user  nobody 修改成其餘用戶, 例如新建用戶nginx, 或openresty, 或tomcat, 若是直接用nobody, 會致使啓動進程一直被阻塞, 在/var/log/secure裏能看到相似以下的權限錯誤

Unregistered Authentication Agent for unix-process:17339:1142872114 (system bus name :1.389659, object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale en_US.utf8) (disconnected from bus)

 

配置Openresty結合Redis進行IP封禁

修改 nginx.conf, 由於使用的是Openresty的安裝包, 因此不須要在前面再設置模塊路徑, 能夠直接引用

# http 下增長
lua_shared_dict ip_blacklist 1m;

# server 下增長
        location /ipblacklist {
            access_by_lua_file lua/ip_blacklist.lua;
            default_type text/html;
            content_by_lua '
                ngx.say("<p>Hello, this is lua.</p>")
            ';
        }

在/usr/local/openresty/nginx/lua下新建 ip_blacklist.lua

-- a quick LUA access script for nginx to check IP addresses against an
-- `ip_blacklist` set in Redis, and if a match is found send a HTTP 403.
--
-- allows for a common blacklist to be shared between a bunch of nginx
-- web servers using a remote redis instance. lookups are cached for a
-- configurable period of time.
--
-- block an ip:
--   redis-cli SADD ip_blacklist 10.1.1.1
-- remove an ip:
--   redis-cli SREM ip_blacklist 10.1.1.1
--
-- also requires lua-resty-redis from:
--   https://github.com/agentzh/lua-resty-redis
--
-- your nginx http context should contain something similar to the
-- below: (assumes resty/redis.lua exists in /etc/nginx/lua/)
--
--   lua_package_path "/etc/nginx/lua/?.lua;;";
--   lua_shared_dict ip_blacklist 1m;
--
-- you can then use the below (adjust path where necessary) to check
-- against the blacklist in a http, server, location, if context:
--
-- access_by_lua_file /etc/nginx/lua/ip_blacklist.lua;
--
-- from https://gist.github.com/chrisboulton/6043871
-- modify by Ceelog

local redis_host    = "192.168.1.18"
local redis_port    = 6379
local redis_auth    = "foobar"
local redis_db       = 3

-- connection timeout for redis in ms. don't set this too high!
local redis_connection_timeout = 100

-- check a set with this key for blacklist entries
local redis_key     = "ip_blacklist"

-- cache lookups for this many seconds
local cache_ttl     = 60

-- end configuration

ngx.log(ngx.DEBUG, "Redis host: " .. redis_host);

local ip                = ngx.var.remote_addr
local ip_blacklist     = ngx.shared.ip_blacklist
local last_update_time     = ip_blacklist:get("last_update_time");

-- only update ip_blacklist from Redis once every cache_ttl seconds:
if last_update_time == nil or last_update_time < ( ngx.now() - cache_ttl ) then

  local redis = require "resty.redis";
  local red = redis:new();

  red:set_timeout(redis_connect_timeout);

  local ok, err = red:connect(redis_host, redis_port);
  if not ok then
    ngx.log(ngx.DEBUG, "Redis connection error while retrieving ip_blacklist: " .. err);
  else
    local ok, err = red:auth(redis_auth);
    if not ok then
      ngx.log(ngx.DEBUG, "Redis auth error while retrieving ip_blacklist:" .. err);
    end
    red:select(redis_db);
    local new_ip_blacklist, err = red:smembers(redis_key);
    if err then
      ngx.log(ngx.DEBUG, "Redis read error while retrieving ip_blacklist: " .. err);
    else
      -- replace the locally stored ip_blacklist with the updated values:
      ip_blacklist:flush_all();
      for index, banned_ip in ipairs(new_ip_blacklist) do
        ip_blacklist:set(banned_ip, true);
      end

      -- update time
      ip_blacklist:set("last_update_time", ngx.now());
    end
  end
end

if ip_blacklist:get(ip) then
  ngx.log(ngx.DEBUG, "Banned IP detected and refused access: " .. ip);
  return ngx.exit(ngx.HTTP_FORBIDDEN);
end

由於這裏設置了緩存, 60s更新一次, 因此不須要再使用redis pool, 若是須要使用pool, 能夠參考

https://github.com/openresty/lua-resty-redis#synopsis

# you do not need the following line if you are using
# the OpenResty bundle:
lua_package_path "/path/to/lua-resty-redis/lib/?.lua;;";

server {
    location /test {
        content_by_lua_block {
            local redis = require "resty.redis"
            local red = redis:new()

            red:set_timeout(1000) -- 1 sec

            -- or connect to a unix domain socket file listened
            -- by a redis server:
            --     local ok, err = red:connect("unix:/path/to/redis.sock")

            local ok, err = red:connect("127.0.0.1", 6379)
            if not ok then
                ngx.say("failed to connect: ", err)
                return
            end
            
            ...
            
            -- put it into the connection pool of size 100,
            -- with 10 seconds max idle time
            local ok, err = red:set_keepalive(10000, 100)
            if not ok then
                ngx.say("failed to set keepalive: ", err)
                return
            end

            -- or just close the connection right away:
            -- local ok, err = red:close()
            -- if not ok then
            --     ngx.say("failed to close: ", err)
            --     return
            -- end
... }

以及

若是你想讓 A 和 B 這兩個不一樣的 redis 後端分別保持最多 32 個長鏈接,則在訪問 A 或者 B 的 resty.redis 對象上都調用 set_keepalive(0, 32),由於默認狀況下不一樣的 redis 後端擁有不一樣的鏈接池。

若是你但願 A 和 B 都共享一個鏈接池,則能夠在 connect() 方法中指定 pool 選項,例如:
    redA:connect("A", 6379, { pool = "my_redis_cluster" })
    redB:connect("B", 6379, { pool = "my_redis_cluster" })

而後在調用 set_keepalive 時使用 64 做爲這個 A、B 共享池的鏈接數上限:
    redA:set_keepalive(0, 64)
    redB:set_keepalive(0, 64)

不過要注意的一點是,鏈接池是每 worker 的粒度,因此實際每一個 redis 後端的總鏈接數上限還要再用 32 剩上 worker 數。
相關文章
相關標籤/搜索