Category Archives

11 Articles

lua-resty-openssl: 基於FFI的Lua OpenSSL庫

0   6785 轉為簡體

支持OpenSSL 1.1.x, 1.0.x和1.0.2系列

lua-resty-acme: ACMEv2客戶端和Let’s Encrypt證書的自動化管理

0   10529 轉為簡體

 

 

安裝

使用opm:

opm中沒有luaossl庫,所以這種安裝使用的是基於FFI的Openssl後端;需要OpenResty鏈接了大於等於1.1版本的OpenSSL。

也可以使用luarocks安裝:

使用

以/etc/openresty目錄為例,如果目錄不存在,請自行修改。

生成一個賬戶密鑰

生成一個默認證書

在Nginx配置的http 節插入以下內容

首次配置時,建議將init_by_lua_block中的staing = true取消注釋,以防錯誤過多觸發限流;測試通過後再加回注釋使用生產API。

在需要使用證書的server節插入

CentOS/Fedora等系統的根證書在/etc/ssl/certs/ca-bundle.crt,請根據實際情況修改lua_ssl_trusted_certificate。

保存後,reload nginx。

在一般情況下,domain_whitelist必須配置,以防止惡意請求通過偽造SNI頭進行拒絕服務攻擊。

如果要匹配一系列域名,可以使用__index來實現。比如下面的例子僅匹配example.com的子域名:

RSA+ECC雙證書

將init_by_lua_block中的domain_key_types = { 'rsa', 'ecc' }取消注釋後,即可同時申請兩套證書。

為了讓申請到證書前的握手不出錯斷開,給Nginx配置默認的ECC證書

然後在server節中原有的ssl_certificate下增加兩行

關於加密套件等的選擇可藉助搜索引擎。

TLS-ALPN-01

0.5.0開始支持tls-alpn-01,可以支持在只開放443端口的環境里完成驗證。方法是通過蜜汁FFI偏移找到當前請求的SSL結構,然後設置了新的ALPN。需要多個stream server多次proxy,拓撲結構如下:

第一個stream server打開了443端口,根據請求的ALPN分發到不同的後段;如果是acme-tls則轉發到我們的庫,否則轉發到正常的https。

示例配置見Github

lua-resty-multiplexer: 端口服務復用

0   9956 轉為簡體

實現了一個端口服務復用的透明代理,可以在同一個端口上運行多個協議。根據每次連接中客戶端發起的首個請求檢測協議,根據協議或各種條件選擇代理的上游。

需要打一個補丁。由@fcicq這個討論中貢獻。這個補丁實現了BSD的socket recv()語義。目前官方也有這個feature的PR

示例配置:

示例中服務監聽在80端口,並定義規則:

  • 如果客戶端來自 10.0.0.1,代理到 internal-host.com:80
  • 如果請求協議是HTTP 而且客戶端來自10.0.0.2,代理到 internal-host:8001
  • 如果請求協議是 SSH,代理到 github.com:22
  • 如果請求協議是 DNS,代理到 1.1.1.1:53
  • 如果請求協議是 SSL/TLS 而且現在的時間是 0 到 30分,代理到 twitter.com:443
  • 如果請求協議是 SSL/TLS 而且現在的時間是 31 到 59分,代理到  www.google.com:443
  • 以上均不滿足,代理到 127.0.0.1:80

說明

  • 只能實現識別連接建立後客戶端先發送請求的協議,不兼容服務端先發送響應的協議(比如FTP,SMTP等)
  • 如果實現了ngx.reqsock.peak(),則可以使用ngx_stream_proxy來轉發流量,這樣的話除了首個請求以外同一連接的後續請求將沒有額外的性能損失;目前只能在Lua層轉發。

Read More

使用Redis協議來調試ngx.shared

0   8894 轉為簡體

有時候用ngx.shared的時候想看一下到底存進去的值是什麼,或者想列一下滿足條件的鍵,或者想批量操作,所以這個項目就是用來解決這個問題的。

除了支持ngx.shared提供的操作以外,學習Redis增加了PING(測試連通性),KEYS(列出符合條件的鍵)和EVAL(在服務器上執行Lua腳本)。

已上傳到opm,可以通過

opm install fffonion/lua-resty-shdict-server

一鍵安裝。

由於目前stream和http子系統是兩個獨立的Lua VM,因此不能通過全局變量來共享數據。另外兩個子系統的shdict是分別定義的,因此也不能互擼。所以如果想用這個模塊來在redis-cli里擼http子系統下定義的shdict,需要這個補丁

示例配置:

然後

 

使用lua-nginx-module緩存JSONP

0   10649 轉為簡體

最近給暢言加上了單點登錄,也就是可以用網站的帳號來在暢言上發射評論。暢言會通過你設置的一個接口來獲得用戶名,頭像等。但是我發現隊友暢言會頻繁請求這個接口,有時候會達到單個用戶一秒鐘好幾次??

雖然在php層有redis,壓力不會很大,但是這樣頻繁的請求還是會中防CC的策略,影響用戶正常的瀏覽。所以我決定在CDN上做個緩存。

Read More