9.1 KiB
+++ 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 反代配置
这里以我所用的 mastadon 所用的配置来举例:
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;
}
}
location = / {
return 418;
}
如果设置为公开读的桶,那么访问域名主页会列出当下桶前面一些数量的对象,这可能会带来一些风险,所以针对直接访问主页的请求直接拒绝并返回。
limit_except GET {
deny all;
}
只允许 HTTP GET 方法,毕竟很多对象存储服务是连失败的请求也要计入费用的。
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 天有效期
add_header 'Access-Control-Allow-Origin' '*';
expires 1y;
proxy_pass [s3-url];
add_header
放行跨域设置,对于联邦宇宙而言有些实例会直接让用户读取源站媒体,所以不能做限制。
expires
设置客户端的缓存失效时间为一年。
proxy_pass
服务商给的桶公开链接。
proxy_intercept_errors on;
error_page 400 403 404 = @fallback;
location @fallback {
return 404;
}
一些服务商的 404 页面里会包含桶名信息,这是一个会被知晓桶名的点。
proxy_intercept_errors
开启后将允许自定义设置错误,将其定位为 nginx
的默认 404 页面。
设置迁移
有时候对一个服务商感到不满准备迁移,例如使用 Rclone 工具将原来的桶拷贝到另一个服务商的桶,对于一个几十上千万的对象的桶来说迁移将是一个漫长的过程。而在迁移时也不可能完全停止服务,但可以在反代层设置一个策略,当找不到对象时可以导向原来的桶,这样对于用户来说也是无感的。具体来说:
- 更改应用程序配置 s3 设置为新服务商,让新写入数据导向新桶
- 编辑
nginx
配置,设置反代为新服务商- 当新服务商报 404 时,往旧服务商的地址再进行反代
- 运行迁移,将旧服务商的桶对象拷贝到新服务商的桶内
具体配置:
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
允许多次定义错误页。
location @fallback {
return 418;
}
不能再返回 404 了否则会陷入循环,可以另选一个其它错误,这里我选择 418 。
免责声明
安全无小事,我也无法保证上面的设置是没有漏洞的或者完全安全的,对使用相关配置带来的后果也不负任何责任。