[post] new post
All checks were successful
/ deploy (push) Successful in 49s

This commit is contained in:
SouthFox 2024-06-22 22:40:56 +08:00
parent d7f3bfa681
commit 12506255f0

View file

@ -0,0 +1,274 @@
+++
title = "对象存储反代设置"
author = ["SouthFox"]
date = 2024-06-22T20:40:00+08:00
lastmod = 2024-06-22T22:40:55+08:00
tags = ["publish"]
draft = false
+++
## 为什么要为对象存储做一层反代? {#为什么要为对象存储做一层反代}
在对象存储商前面挂一层[反向代理]({{< relref "../main/nw_反向代理.md" >}})做一层[缓存]({{< relref "../main/nw_缓存.md" >}})是一个好主意,可以压缩请求数和流量,节省消费开支。同时挡下一些恶意请求。
对象存储很多服务商都是有着「请求数」和「流量」的计费项目,如果被有心之人大量恶意请求那么就有可能产生高额账单。
## 对策 {#对策}
- 创建桶名时为其添加随机后缀
- 最好不要直接使用服务商提供的链接
- 设置为公开读的桶最好做一层反代
## Nginx 反代配置 {#nginx-反代配置}
这里以我所用的 mastadon 所用的配置来举例:
```cfg
proxy_cache_path /tmp/nginx_mstdn_media levels=1:2 keys_zone=mastodon_media:100m max_size=1g inactive=24h;
server {
listen 80;
listen [::]:80;
server_name [media-host];
return 301 https://[media-host]$request_uri;
access_log /dev/null;
error_log /dev/null;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name [media-host];
ssl_certificate /etc/letsencrypt/live/[media-host]/fullchain.pem; # ma>
ssl_certificate_key /etc/letsencrypt/live/[media-host]/privkey.pem; # >
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
access_log /var/log/nginx/mstdn-media-access.log;
error_log /var/log/nginx/mstdn-media-error.log;
location = / {
return 418;
}
location / {
limit_except GET {
deny all;
}
proxy_cache mastodon_media;
proxy_cache_revalidate on;
proxy_buffering on;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;
proxy_cache_valid 30d;
proxy_cache_valid 404 1h;
proxy_hide_header 'Access-Control-Allow-Origin';
proxy_hide_header 'Access-Control-Allow-Methods';
proxy_hide_header 'Access-Control-Allow-Headers';
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header x-amz-meta-server-side-encryption;
proxy_hide_header x-amz-server-side-encryption;
proxy_hide_header x-amz-bucket-region;
proxy_hide_header x-amzn-requestid;
proxy_hide_header x-amz-version-id;
proxy_ignore_headers Set-Cookie;
proxy_ignore_headers Cache-Control;
add_header X-Cached $upstream_cache_status;
add_header 'Access-Control-Allow-Origin' '*';
expires 1y;
proxy_pass [s3-url];
}
proxy_intercept_errors on;
error_page 400 403 404 = @fallback;
location @fallback {
return 404;
}
}
```
```cfg
location = / {
return 418;
}
```
如果设置为公开读的桶,那么访问域名主页会列出当下桶前面一些数量的对象,这可能会带来一些风险,所以针对直接访问主页的请求直接拒绝并返回。
```cfg
limit_except GET {
deny all;
}
```
只允许 HTTP GET 方法,毕竟很多对象存储服务是连失败的请求也要计入费用的。
```cfg
proxy_cache_path /tmp/nginx_mstdn_media levels=1:2 keys_zone=mastodon_media:100m max_size=1g inactive=24h;
...
proxy_cache mastodon_media;
proxy_cache_revalidate on;
proxy_buffering on;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;
proxy_cache_valid 30d;
proxy_cache_valid 404 1h;
```
`nginx` 缓存设置,缓存到服务器本地并设置为 30 天有效期
```cfg
add_header 'Access-Control-Allow-Origin' '*';
expires 1y;
proxy_pass [s3-url];
```
`add_header` 放行跨域设置,对于联邦宇宙而言有些实例会直接让用户读取源站媒体,所以不能做限制。
`expires` 设置客户端的缓存失效时间为一年。
`proxy_pass` 服务商给的桶公开链接。
```cfg
proxy_intercept_errors on;
error_page 400 403 404 = @fallback;
location @fallback {
return 404;
}
```
一些服务商的 404 页面里会包含桶名信息,这是一个会被知晓桶名的点。
`proxy_intercept_errors` 开启后将允许自定义设置错误,将其定位为 `nginx` 的默认 404 页面。
## 设置迁移 {#设置迁移}
有时候对一个服务商感到不满准备迁移,例如使用 [Rclone](https://rclone.org/) 工具将原来的桶拷贝到另一个服务商的桶,对于一个几十上千万的对象的桶来说迁移将是一个漫长的过程。而在迁移时也不可能完全停止服务,但可以在反代层设置一个策略,当找不到对象时可以导向原来的桶,这样对于用户来说也是无感的。具体来说:
- 更改应用程序配置 s3 设置为新服务商,让新写入数据导向新桶
- 编辑 `nginx` 配置,设置反代为新服务商
- 当新服务商报 404 时,往旧服务商的地址再进行反代
- 运行迁移,将旧服务商的桶对象拷贝到新服务商的桶内
具体配置:
```cfg
proxy_cache_path /tmp/nginx_mstdn_media levels=1:2 keys_zone=mastodon_media:100m max_size=1g inactive=24h;
server {
listen 80;
listen [::]:80;
server_name [media-host];
return 301 https://[media-host]$request_uri;
access_log /dev/null;
error_log /dev/null;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name [media-host];
ssl_certificate /etc/letsencrypt/live/[media-host]/fullchain.pem; # ma>
ssl_certificate_key /etc/letsencrypt/live/[media-host]/privkey.pem; # >
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
access_log /var/log/nginx/mstdn-media-access.log;
error_log /var/log/nginx/mstdn-media-error.log;
location / {
limit_except GET {
deny all;
}
proxy_cache mastodon_media;
proxy_cache_revalidate on;
proxy_buffering on;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;
proxy_cache_valid 30d;
proxy_cache_valid 404 1h;
proxy_hide_header 'Access-Control-Allow-Origin';
proxy_hide_header 'Access-Control-Allow-Methods';
proxy_hide_header 'Access-Control-Allow-Headers';
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header x-amz-meta-server-side-encryption;
proxy_hide_header x-amz-server-side-encryption;
proxy_hide_header x-amz-bucket-region;
proxy_hide_header x-amzn-requestid;
proxy_hide_header x-amz-version-id;
proxy_ignore_headers Set-Cookie;
proxy_ignore_headers Cache-Control;
add_header X-Cached $upstream_cache_status;
add_header 'Access-Control-Allow-Origin' '*';
expires 1y;
proxy_pass [new-s3-url];
}
proxy_intercept_errors on;
recursive_error_pages on;
error_page 400 403 404 = @404;
location @404 {
proxy_pass [old-s3-url];
proxy_hide_header 'Access-Control-Allow-Origin';
proxy_hide_header 'Access-Control-Allow-Methods';
proxy_hide_header 'Access-Control-Allow-Headers';
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header x-amz-meta-server-side-encryption;
proxy_hide_header x-amz-server-side-encryption;
proxy_hide_header x-amz-bucket-region;
proxy_hide_header x-amzn-requestid;
proxy_hide_header x-amz-version-id;
proxy_ignore_headers Set-Cookie;
proxy_ignore_headers Cache-Control;
error_page 400 403 404 = @fallback;
}
location @fallback {
return 418;
}
}
```
其中新增加内容并不多:
`recursive_error_pages` 允许多次定义错误页。
```cfg
location @fallback {
return 418;
}
```
不能再返回 404 了否则会陷入循环,可以另选一个其它错误,这里我选择 418 。
## 免责声明 {#免责声明}
安全无小事,我也无法保证上面的设置是没有漏洞的或者完全安全的,对使用相关配置带来的后果也不负任何责任。
## 参考 {#参考}
[Proxying object storage through nginx | Mastodon Docs](https://docs.joinmastodon.org/admin/optional/object-storage-proxy/)
[云上黑暗森林打爆云账单只需要S3桶名 | Pigsty](https://pigsty.io/zh/blog/cloud/s3-scam/)