使用 nginx 代理为 googlebot 等机器人提供静态 S3 到不同的存储桶
Using nginx proxy to serve static S3 to a different bucket for bots like googlebot
使用 nginx 将 superduper.io 的子域代理到 S3 存储桶中的特定文件夹。该存储桶为每个包含静态 HTML 网站的子域都有一个文件夹。
现在我想将机器人重定向到不同的 S3 存储桶。我需要在我的 nginx.conf 文件中添加什么?
worker_processes auto;
# include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
server {
listen 80;
server_name *.superduper.io;
access_log /var/log/nginx/superduper.access.log;
error_log /var/log/nginx/superduper.error.log;
location / {
resolver 8.8.8.8;
set $bucket "https://superduper-spa.s3.us-east-1.amazonaws.com:443";
rewrite ^([^.]*[^/])$ / permanent;
# matches: subdomain.superduper.io
if ($host ~ ^([^.]*)\.superduper\.io) {
set $subdomain ;
proxy_pass https://$bucket/${subdomain}${uri};
}
proxy_intercept_errors on;
proxy_redirect off;
proxy_set_header Host $bucket;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
}
}
# include /etc/nginx/conf.d/*.conf;
# include /etc/nginx/sites-enabled/*;
}
由于 nginx 不支持 else
语句,也不支持具有多个条件的 if
,因此编写依赖于多个变量的某些配置可能会变得棘手。
对于您的用例,潜在解决方案有两个改进,可以一起使用或分开使用:
您可能希望将现有的 if
与围绕 $host
的正则表达式转换为 命名捕获 server_name
根据 http://nginx.org/r/server_name。这样,您就可以自由地使用围绕 $http_user_agent
匹配机器人所需的任何转换,例如,通过使用更像是实际条件的 if
语句,而不仅仅是捕获子域。
-server_name *.example.su;
-if ($host ~ ^([^.]*)\.example\.su$) {
- set $subdomain
-}
+server_name ~^(p<subdomain>[^.]*)\.example\.su$;
您可能想使用 http://nginx.org/r/map。它允许将任何输入映射到输出。您可以组合 $host
和 $http_user_agent
的匹配项来进行转换。
map $http_host/$http_user_agent $bucket {
"~^(p<subdomain>[^.]*)\.example\.su.*bot.*$" $bucketPrefix/$subdomain/bot;
"~^(p<subdomain>[^.]*)\.example\.su.*$" $bucketPrefix/$subdomain;
default $bucketPrefix;
}
server {
…
proxy_pass $bucket$uri;
}
替代解决方案是在 S3 前面使用 Cloudfront,然后使用 Lamdbda at edge 函数将特定 user-agents 重定向到不同的存储桶,而无需接触 nginx。
使用 nginx 将 superduper.io 的子域代理到 S3 存储桶中的特定文件夹。该存储桶为每个包含静态 HTML 网站的子域都有一个文件夹。
现在我想将机器人重定向到不同的 S3 存储桶。我需要在我的 nginx.conf 文件中添加什么?
worker_processes auto;
# include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
server {
listen 80;
server_name *.superduper.io;
access_log /var/log/nginx/superduper.access.log;
error_log /var/log/nginx/superduper.error.log;
location / {
resolver 8.8.8.8;
set $bucket "https://superduper-spa.s3.us-east-1.amazonaws.com:443";
rewrite ^([^.]*[^/])$ / permanent;
# matches: subdomain.superduper.io
if ($host ~ ^([^.]*)\.superduper\.io) {
set $subdomain ;
proxy_pass https://$bucket/${subdomain}${uri};
}
proxy_intercept_errors on;
proxy_redirect off;
proxy_set_header Host $bucket;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
}
}
# include /etc/nginx/conf.d/*.conf;
# include /etc/nginx/sites-enabled/*;
}
由于 nginx 不支持 else
语句,也不支持具有多个条件的 if
,因此编写依赖于多个变量的某些配置可能会变得棘手。
对于您的用例,潜在解决方案有两个改进,可以一起使用或分开使用:
您可能希望将现有的
if
与围绕$host
的正则表达式转换为 命名捕获server_name
根据 http://nginx.org/r/server_name。这样,您就可以自由地使用围绕$http_user_agent
匹配机器人所需的任何转换,例如,通过使用更像是实际条件的if
语句,而不仅仅是捕获子域。-server_name *.example.su; -if ($host ~ ^([^.]*)\.example\.su$) { - set $subdomain -} +server_name ~^(p<subdomain>[^.]*)\.example\.su$;
您可能想使用 http://nginx.org/r/map。它允许将任何输入映射到输出。您可以组合
$host
和$http_user_agent
的匹配项来进行转换。map $http_host/$http_user_agent $bucket { "~^(p<subdomain>[^.]*)\.example\.su.*bot.*$" $bucketPrefix/$subdomain/bot; "~^(p<subdomain>[^.]*)\.example\.su.*$" $bucketPrefix/$subdomain; default $bucketPrefix; } server { … proxy_pass $bucket$uri; }
替代解决方案是在 S3 前面使用 Cloudfront,然后使用 Lamdbda at edge 函数将特定 user-agents 重定向到不同的存储桶,而无需接触 nginx。