最近的 nginx + php-fpm 安全性漏洞

這次的漏洞是在打 CTF (capture the flag) 的時候發現的,這個安全漏洞已經被給 CVE 編號並且修正了:「CVE-2019-11043」,回報者與官方的討論可以在「Sec Bug #78599 env_path_info underflow in fpm_main.c can lead to RCE」這邊看到。從回報的標題可以知道這次頗熱鬧的原因,是因為這次有機會 RCE (remote code execution)...

在「PHuiP-FPizdaM」這邊可以看到比較系統性的整理 (以及 exploit),看起來雖然有不少條件,但都不算太特別的指令,如果以全世界的機器來看,應該會有不少機器中獎...

補上 nginx 對 favicon 的壓縮...

從「Compressed favicons are 70% smaller but 75% of them are served uncompressed」這邊看到的,他們發現大約有 73.5% 的網站沒有壓縮 favicon.ico 檔:

The HTTP Archive dataset of favicons from 4 million websites crawled from desktop devices on May 2019 shows that 73,5 % of all favicons are offered without any compression with an average file size of 10,5 kiB, 21,5 % are offered with Gzip compression at an average file size of 4 kiB, and 5 % offer Brotli compression at an average file size of 3 kiB.

我自己的也沒加... 補上 gzip 相關的設定後,favicon.ico 的傳輸量從 4.2KB 降到 1.2KB。

我是使用 nginx,在 Ubuntu 上 nginx 的 nginx.conf 內 gzip 預設已經有開,所以只要增加一些設定讓他知道要處理 ico 檔案就可以了。

方法是在 /etc/nginx/conf.d/gzip.conf 裡面放:

gzip_comp_level 9;
gzip_types image/vnd.microsoft.icon image/x-icon;
gzip_vary on;

跟文章裡面提到的多了兩個設定,一個是 gzip_comp_level 改成 9 (預設是 1),另外有 gzip 時應該要在 Vary 表示,避免 cache 出錯。

F5 買下 NGINX Inc.

F5 宣佈併購 NGINX Inc.,雙方的新聞稿都出來了:「F5 Acquires NGINX to Bridge NetOps & DevOps, Providing Customers with Consistent Application Services Across Every Environment」、「NGINX to Join F5: Proud to Finish One Chapter and Excited to Start the Next」。

SEATTLE and SAN FRANCISCO – F5 Networks, Inc. (NASDAQ: FFIV) and NGINX today announced a definitive agreement under which F5 will acquire all issued and outstanding shares of privately held NGINX for a total enterprise value of approximately $670 million, subject to certain adjustments.

印象中 NGINX Inc. 的文章常常在批評 F5 這類 load balancer 太貴,現在是在演哪齣戲... 然後這不知道對 open source community 來說是不是好下場,也許如果真的發現風頭不對的話就會有人 fork?(AWS?他們最近好像對這個議題頗敏感 XDDD)

升級 nginx 後關不掉的 TLSv1.3...

我 blog 的 nginx 是用 ondrej 的版本,最近他把套件加上 TLSv1.3 的支援 (主要是 OpenSSL 1.1.1 出了),但不知道是哪個環節出問題了,現在 TLSv1.3 關不掉 XDDD

而且包起來的 OpenSSL 很奇怪,不管什麼情況都會把 TLSv1.3 的三個 cipher 放進來:

gslin@colo-vultr-1 [~] [17:38] openssl ciphers -v 'xxx'     
TLS_AES_256_GCM_SHA384  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(256) Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any      Au=any  Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(128) Mac=AEAD

然後 nginx 只設 TLSv1.2 的情況下,用 SSL Labs 的網站掃還是會有 TLSv1.3:

ssl_protocols TLSv1.2;

然後還有遇到改了 cipher 後,跑 pkill -1 nginx 之後 client 端會回報沒有任何 cipher 可以用,直到跑了 service nginx restart 後就好的情況...

建議想用的人再等一下...

nginx 1.15.2 開始支援單一 Port 多服務...

nginx 的新功能,單一 port 支援多服務:「Running SSL and Non-SSL Protocols over the Same Port with NGINX 1.15.2」,最常見的還是混搭 SSH 了:

One key feature in this release is the new $ssl_preread_protocol variable, which allows you to distinguish between SSL/TLS and other protocols when forwarding traffic using a TCP (stream) proxy. This is useful if you want to avoid firewall restrictions by (for example) running SSL/TLS and SSH services on the same port.

雖然 L7 firewall 還是可以看出來 (並且擋下),但簡易的 firewall 就可以用這個方式穿過去了...

nginx 推出了 1.14.0 的 PPA

nginxPPA (「NGINX Stable : “Nginx” team」這個) 推出了 1.14.0 的版本。

這個版本使用了 OpenSSL 1.1.0,對 cipher 這塊最大的差異主要是包括了 CHACHA20AESCCM 演算法。後者的 CCM 指的是 CCM mode,這是當時 OCB mode 因為專利問題而發展出來的演算法,就目前的效能測試沒有 GCM 好,而且普及率也沒有 GCM 高,放進來應該是當備案 (當 GCM 有狀況時標準裡至少有方案可以選):

The catalyst for the development of CCM mode was the submission of OCB mode for inclusion in the IEEE 802.11i standard. Opposition was voiced to the inclusion of OCB mode because of a pending patent application on the algorithm. Inclusion of a patented algorithm meant significant licensing complications for implementors of the standard.

真正的重點在於 CHACHA20 的引入,讓 OpenSSL 重新有主流 stream cipher 可以使用了... 上一個主流 stream cipher RC4 被打趴好久了。

不過 TLSv1.3 要等 OpenSSL 1.1.1 才有 (參考「Using TLS1.3 With OpenSSL」這邊的說明),目前可以在設定檔裡面設 TLSv1.3 而不會出現錯誤訊息,但暫時還不會有效果...

nginx 穩定版 1.14.0 出版

Twitter 上看到 nginx 穩定版 1.14.0 出了:

CHANGES-1.14 可以看到 1.12 到 1.14 中間多了哪些功能,我比較注意的是:

  • 引入了 TLS 1.3 關鍵字。(因為還沒進 Standard Track,不能直接說支援了...)
  • 支援 HTTP/2 Push。
  • 引入 gRPC 相關的功能。

看看 Ubuntu 18.04 會不會直接上這個版本,另外就是等 PPA 了...

在 nginx 環境中把 Trac 裝到子目錄下的設法

以前的「Nginx + FastCGI + Trac」提到給的範例是把 Trac 裝在 / 下的方法。如果是裝在 /trac 或是其他路徑時就需要修改了。

一開始試著改會出現這樣的錯誤:

No handler matched request to /trac/report/7

然後研究調整後,發現 Trac 純粹是吃 FastCGI 給的參數去判斷要怎麼處理 url routing,在 trac.ini 內 url 相關參數主要還是用在其他地方... (像是信件通知時用的 url)

首先是把檔案簡化,這是 2016 年寫的:

    location / {
        auth_basic "trac realm";
        auth_basic_user_file /srv/domain.example.com/.htpasswd;

        include fastcgi.conf;
        fastcgi_param AUTH_USER $remote_user;
        fastcgi_param HTTPS on;
        fastcgi_param PATH_INFO $fastcgi_script_name;
        fastcgi_param REMOTE_USER $remote_user;
        fastcgi_param SCRIPT_NAME "";
        fastcgi_pass unix:/var/run/trac/trac.sock;
    }

發現現在 fastcgi.conf 內都會處理 HTTPS 了,所以拿掉 HTTPS 的處理,然後把 location 的判斷改用 regex 去抓 /trac 後的東西,所以先變成這樣:

    location ~ /trac(/.*) {
        auth_basic "trac realm";
        auth_basic_user_file /srv/domain.example.com/.htpasswd;

        include fastcgi.conf;
        fastcgi_param AUTH_USER $remote_user;
        fastcgi_param PATH_INFO $fastcgi_script_name;
        fastcgi_param REMOTE_USER $remote_user;
        fastcgi_param SCRIPT_NAME "";
        fastcgi_pass unix:/var/run/trac/trac.sock;
    }

最後是把 PATH_INFO 改傳 $1 (在 / 的情境下 $fastcgi_script_name 剛好就會是 routing 用的 PATH_INFO 資訊,所以當時直接拿來用),把 SCRIPT_NAME 改成 /trac

也就是跟 Trac 說基底在 /trac,後面的路徑才是你的 routing engine 要處理的東西,所以變成:

    location ~ /trac(/.*) {
        auth_basic "trac realm";
        auth_basic_user_file /srv/domain.example.com/.htpasswd;

        include fastcgi.conf;
        fastcgi_param AUTH_USER $remote_user;
        fastcgi_param PATH_INFO $1;
        fastcgi_param REMOTE_USER $remote_user;
        fastcgi_param SCRIPT_NAME "/trac";
        fastcgi_pass unix:/var/run/trac/trac.sock;
    }

沒寫下來就會花不少時間重新摸...

nginx 的 HTTP/2 要支援 Server Push 了

Twitter 上看到 nginx 的 HTTP/2 也要支援 server push 的消息了:

看起來是只要送出對應的 HTTP Header,後續 nginx 就會幫你處理...

這功能總算是要進 nginx 了... 像是透過 cookie 判斷使用者是第一次瀏覽,就透過 server push 預先把 css/js 丟出去,加速頁面呈現。