顯示具有 nginx 標籤的文章。 顯示所有文章
顯示具有 nginx 標籤的文章。 顯示所有文章

2025年8月8日 星期五

靜態資源快取怎麼做?

前言

很難得一天發兩篇文,還都不是我的本業文(算了我也不是第一天不務正業

總之後端反應為什麼前端會重複下載靜態資源,請我去查(乾~這又關前端什麼事

我再度拿我的專案去問gemini-cli,他給我的檢查方式是看network,靜態資源檔的size,如果顯示為disk cache或memory cache,那就是正常快取,如果為容量,那就是沒有快取(我以為是看status301,問了才知道301是轉址,好在不是問維運不然一定被嗆爆

這邊有個要注意的點,注意network頁的disabled cache不要打勾,不然你永遠看不到快取(我就這樣犯傻浪費了些時間

以下這張圖就是有拿到快取


假設沒有快取,如果你想在nginx上設置,可以加上以下配置,時間可以自訂

location ~* \.(jpg|jpeg|gif|png|svg|ico|webp)$ {
# 快取有效期設為一天
expires 1d;
# 明確設定 Cache-Control 標頭
# public: 可被任何快取(包括 CDN 和代理伺服器)快取
# immutable: 告訴瀏覽器這個檔案內容絕對不會改變,不需要為了驗證而重新發送請求
add_header Cache-Control "public, max-age=86400, immutable";
# 可選:關閉這個 location 的存取日誌,減少 I/O
access_log off;
}

這樣應該就可以做到一天快取

小結

結果在我們站上,我把nginx設定拉掉,快取還是在啊,強烈懷疑那位後端把disabled cache打溝了,但我沒有證據......好拉快點讓我下班吧==

2023年12月8日 星期五

nginx X-Frame-Options & proxy

前言
我都覺得我快變成維運了,全端工程師已經夠可憐了,最近寫的文章全部都是為運相關....

內文
好好一個案子說“弱掃”掃描不過有安全性問題

其中一條說
Missing Anti-clickjacking Header: 在HTTP Header加入X-Frame-Options: DENY或SAMEORIGIN
然後附上一段參考網址
https://a42033.gitbooks.io/system/content/security/user/X_Frame_Options.html

我去研究一下發現這是關於自己往也能否被iframe嵌入的設定,理論上當然要不行,或者同域名才可以
所以我參考這個網頁

因為我伺服器是用nginx,所以我就只打關鍵字拉
在default.conf裡面加上
add_header X-Frame-Options DENY;
這樣就搞定了。


至於還有一個比較大條的,安全性等級比較高的問題寫到

Cloud Metadata Potentially Exposed
參考網址
https://www.nginx.com/blog/trust-no-one-perils-of-trusting-user-input/

老實說他只舉出錯誤的寫法,沒有指出正確該怎麼寫.....所以咧~~
最後我看留言,有一個可憐的老哥跟我有一樣的問題:所以呢,是要怎麼解決!!然後他給出他修改的範例,請作者指教。好在作者還真的有回應他,並且是正向的。(媽的他寫對就說一句“對”很難嗎,我看完google translate文鄒鄒落落長,都不知道你在說什麼)

簡單結論一下,文章指出如果直接寫
proxy_pass http://$host;
這樣會有相對的風險,官方“不建議”這樣寫,所以比較好的寫法是透過upstream去指定host
upstream a_node_app {
server 127.0.0.1:3011;
}
我記得這是用來做low balance的,所以就是我指定到upstream的一個host,再由他幫忙轉到我要的位址,這樣就可以了。

後記
文章給的另一個解法是可以架防火牆,至於怎麼用....等我哪天真的轉維運再告訴你

2023年10月26日 星期四

docker,或者說docker-compoes踩的小坑,nginx host name指向問題

先附上我寫的docker-compose

情境說明
我在構思前後端架構時,後端用nodejs,然後前端用nginx,這沒什麼問題,然後因為要走ssl,我懶得把ssl key也copy到後端專案,打算直接在nginx用proxy的方式做掉,OK事情就是這樣發生了,先附上docker-compose跟nginx設定

# docker-compose.yml
version: "3.6"

services:
node-api:
build:
context: .
dockerfile: Dockerfile
container_name: stemi_node_api
volumes:
- ./tmp:/app/tmp
working_dir: /app
command: sh -c "yarn dev"
ports:
- 8000:3333
depends_on:
- python-api
environment:
- PYTHON_API_HOST=python-api

nginx:
build:
context: web
dockerfile: Dockerfile
ports:
- "443:443"
- "3333:3333"
container_name: nginx
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./nginx:/etc/nginx/conf.d
- ../ssl/:/ssl
depends_on:
- node-api

# nginx/default.conf
# ...前端設定省略,因為這不是今天踩坑的主題
server {
listen 3333 ssl;
server_name localhost;
ssl_certificate /ssl/certificate.crt;
ssl_certificate_key /ssl/private.key;

# 根目錄
location / {
proxy_pass http://node-api:8000;
}
}

這一切乍看之下都很完美,但實際在打https://127.0.0.1:3333卻會報502,意思就是打不到東西,我一開始是想是不是node-api讀不到的關係,查了很多關於links, depends_on, networks的文件,最後進到nginx container裡面實際下指令nslookup node-api也確實有,ping也ping得到

/app # nslookup node-api
Server:         127.0.0.11
Address:        127.0.0.11:53
Non-authoritative answer:
Non-authoritative answer:
Name:   node-api
Address: 172.23.0.2

/app # ping node-api
PING node-api (172.23.0.2): 56 data bytes
64 bytes from 172.23.0.2: seq=0 ttl=64 time=0.465 ms
64 bytes from 172.23.0.2: seq=1 ttl=64 time=0.387 ms
^C

後來我發現,我啟動的container也只有兩個,但ip卻有三個
172.23.0.1
172.23.0.2 <= node-api
172.23.0.3 <= nginx
ok問題來了,照上面指令2應該就是node-api,3應該是nginx,那1是什麼呢?我繼續下指令curl -G http://172.23.0.1:8000

/app # curl -G http://172.23.0.1:8000 {"code":0,"data":"ok"}/app #

矮油這下問題嚴重了,我一度以為docker出問題,把host name指向錯誤的主機,想上網找但關鍵字也不知道怎麼下

後來在苦無對策之際,最後試著下一個指令

/app # curl -G http://node-api:3333
{"code":0,"data":"ok"}/app #

一切都真相大白了,我一直以為container是在各自的容器(我不知道這專有名詞是啥,只是講container會搞混,在我想像中他形式比較像沙箱跟區網的概念,將箱子也不好聽,所以就叫中文的容器吧),藉由expose把port開出來讓外界使用,事實上如果用docker-compose那大家就會在同一個容器內,所以網內互打是打原本的port不是export的port,所以1應該就是最後所有container的集合....吧,所以最終只要這樣修改就好。

# nginx/default.conf
  location / {
proxy_pass http://node-api:3333; # 把port改掉
}

因此最終node-api的ports設定也可以拿掉。


我也不是專業的devpos,就是專案需要所以簡單地摸了一下,踩了坑就記錄一下,歡迎不大家吝嗇指教,只是希望可以噴得小力一點!