OSS の IP アドレスは動的に変更されるため、ファイアウォールの許可リストや固定 IP を前提とした統合が機能しなくなる可能性があります。安定した IP を介して OSS にアクセスするには、固定パブリック IP (EIP) を持つ ECS インスタンスに Nginx リバースプロキシをデプロイします。
仕組み
固定パブリック IP を持つ ECS インスタンスがトラフィックのエントリーポイントとなります。Nginx は次のようにリクエストを OSS に転送します。
-
クライアントは、ECS インスタンスの固定パブリック IP (EIP) を介して OSS リソースをリクエストします。
-
ECS インスタンス上の Nginx がリクエストを受信します。
-
Nginx はリクエストを対象の OSS バケットに転送します。
-
OSS はリクエストを処理し、レスポンスを Nginx に返します。
-
Nginx はレスポンスをクライアントに返します。
ECS リバースプロキシの設定
ステップ 1:ECS インスタンスの作成
Nginx リバースプロキシをホストするための ECS インスタンスを作成します。
-
以下の設定で ECS インスタンスを作成します。その他のパラメーターはデフォルト値のままにします。
-
[支払いオプション]:[従量課金] を選択します。
-
リージョン:プロキシ対象の OSS バケットと同じリージョンを選択します。これにより、内部エンドポイントを使用してトラフィックコストを削減できます。
-
ネットワークとゾーン:デフォルトの VPC とアベイラビリティーゾーンを選択します。
-
[インスタンスタイプ]:[すべてのインスタンスタイプ] をクリックし、
ecs.e-c1m2.largeを検索して選択します。説明このインスタンスタイプが在庫切れの場合は、別のインスタンスタイプを選択してください。
-
イメージ:パブリックイメージ > [Alibaba Cloud Linux] (Alibaba Cloud Linux 3.2104 LTS 64-bit) を選択します。
-
システムディスク:[ESSD Entry] ディスクの容量を 40 GiB に設定します。
-
パブリック IP:パブリック IPv4 アドレスの割り当て を選択します。
-
[課金方法]:コストを削減するために [トラフィック課金] を選択します。
-
[ピーク帯域幅]:5 Mbps 以上を選択します。
-
セキュリティグループ:[セキュリティグループの作成] を選択し、[IPv4ポート/プロトコルを開く] で HTTP (TCP:80) を選択して Nginx のリッスンポートを開きます。
-
[ログイン認証]:パスワード を選択し、ユーザー名を root に設定して パスワード を作成します。パスワードは安全に保管してください。
-
ステップ 2:Nginx リバースプロキシの設定
ECS インスタンスに Nginx をインストールし、リバースプロキシのルールを設定します。
-
Nginx をインストールします。
yum install -y nginx -
管理しやすくするため、
/etc/nginx/conf.d/ディレクトリにoss_proxy.confなどの個別の設定ファイルを作成します。vi /etc/nginx/conf.d/oss_proxy.conf以下の設定テンプレートをファイルにコピーし、コメントに示されているプレースホルダーの値を置き換えます。
説明バケットの内部エンドポイント経由でファイルにアクセスすると、ブラウザはインラインで表示する代わりにダウンロードする動作になります。インラインプレビューを有効にするには、
Hostヘッダーをバケットに紐付けられたカスタムドメイン名に設定します。# OSS バックエンドを定義し、接続の再利用を有効にしてパフォーマンスを向上させます。 upstream oss_backend { # [必須] バケットの内部エンドポイントに置き換えてください。 server your-bucket.oss-cn-hangzhou-internal.aliyuncs.com:80; # 推奨される keepalive 接続数。同時リクエスト数に基づいて調整してください。 keepalive 64; } # アップストリームの応答時間などの主要情報を含む、本番環境向けのログ形式を定義します。 log_format production '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' 'rt=$request_time uct="$upstream_connect_time" uht="$upstream_header_time" urt="$upstream_response_time"'; server { listen 80; # [必須] ECS インスタンスのパブリック IP アドレスまたはその IP アドレスに解決されるドメイン名に置き換えてください。 server_name your_ecs_public_ip_or_domain; # アクセスログのパスと形式。 access_log /var/log/nginx/oss_proxy.access.log production; error_log /var/log/nginx/oss_proxy.error.log; # 動的 DNS リゾルバーを使用して、Nginx が OSS バックエンドの IP アドレス変更を認識できるようにします。 resolver 100.100.2.136 100.100.2.138 valid=60s; # ロードバランサーまたは監視システム用のヘルスチェックエンドポイント。 location /health { access_log off; return 200 "healthy"; } location / { # 上記で定義されたアップストリームの OSS バックエンドにリクエストをプロキシします。 proxy_pass http://oss_backend; # 主要な設定:HTTP/1.1 と keepalive 接続が有効になっていることを確認します。 proxy_http_version 1.1; proxy_set_header Connection ""; # 主要な設定:Host ヘッダーをバケットの内部エンドポイントに設定して、Signature V4 検証が成功するようにします。 # [必須] バケットの内部エンドポイントに置き換えてください。 proxy_set_header Host "your-bucket.oss-cn-hangzhou-internal.aliyuncs.com"; # クライアントの実際の IP アドレスを転送します。 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; # プロキシのタイムアウト値を設定します。 proxy_connect_timeout 10s; proxy_send_timeout 30s; proxy_read_timeout 30s; # ファイルアップロードの最大サイズ。0 は無制限を意味します。業務要件に応じてこの値を設定してください。 client_max_body_size 1024m; } }エディターを保存して終了します。
-
Nginx 設定ファイルの構文を確認します。
nginx -t出力に
syntax is okとtest is successfulが含まれている場合、設定は有効です。 -
Nginx サービスを開始して設定を適用します。
systemctl start nginx
リバースプロキシの検証
バケットのアクセス権限に基づいてプロキシを検証します。
パブリック読み取りおよびパブリック読み書きバケット
ブラウザで http://ecs_public_ip/object_path にアクセスします。ecs_public_ip を ECS インスタンスのパブリック IP (ECS コンソールで確認) に、object_path をバケット内のオブジェクトのパスに置き換えます。たとえば、exampledir ディレクトリ内の dest.jpg の場合、object_path は exampledir/dest.jpg です。
ブラウザで dest.jpg ファイルにアクセスすると、システムの [保存] ダイアログボックスが開かれ、ファイルをコンピューターに保存できます。
プライベートバケット
コンソールからオブジェクトの署名付き URL を取得します。署名の詳細については、「署名バージョン 4 (推奨)」をご参照ください。
-
[バケット] リストに移動し、対象のバケットをクリックします。
-
アクセスしたいオブジェクトの 詳細 列で [詳細の表示] をクリックします。
-
オブジェクト URL のコピー をクリックします。コピーした URL で、https を http に置き換え、バケットドメイン名を ECS インスタンスのパブリック IP アドレスに置き換えます。
-
ブラウザで変更後の URL にアクセスします。
ブラウザでファイル dest.jpg の [名前を付けて保存] ダイアログボックスが開きます。これにより、署名付き URL がプライベートオブジェクトに正常にアクセスし、ダウンロードをトリガーしたことを確認できます。
本番環境での推奨事項
本番環境での安定性、セキュリティ、および費用対効果を確保するために、以下の方法を推奨します。
ベストプラクティス
-
高可用性アーキテクチャ:単一障害点を排除するために、アベイラビリティーゾーンをまたいで複数の ECS インスタンスを配置し、SLB を使用します。
-
HTTPS の有効化:転送中のデータを保護するために HTTPS を有効化します。Nginx 用に SSL 証明書を設定し、HTTP を HTTPS にリダイレクトします。設定例:
説明ECS セキュリティグループでポート 443 を許可します。「セキュリティグループルールの追加、変更、または削除」をご参照ください。
# ... upstream と log_format の設定は変更ありません。 ... # HTTP サーバーブロック:すべての HTTP リクエストを HTTPS にリダイレクトします。 server { listen 80; # [必須] ECS インスタンスのパブリック IP アドレスまたはその IP アドレスに解決されるドメイン名に置き換えてください。 server_name your_ecs_public_ip_or_domain; # 301 リダイレクトを使用して、すべての HTTP リクエストを HTTPS にリダイレクトします。 return 301 https://$host$request_uri; } # HTTPS サーバーブロック:実際のプロキシサービスを処理します。 server { # SSL 接続のためにポート 443 でリッスンします。 listen 443 ssl http2; # [必須] ECS インスタンスのパブリック IP アドレスまたはその IP アドレスに解決されるドメイン名に置き換えてください。 server_name your_ecs_public_ip_or_domain; # --- SSL 証明書の設定 --- # [必須] SSL 証明書とプライベートキーファイルへのパスに置き換えてください。 ssl_certificate /path/to/your/fullchain.pem; ssl_certificate_key /path/to/your/private.key; # --- SSL セキュリティ強化 --- ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384'; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # アクセスログのパスと形式。 access_log /var/log/nginx/oss_proxy.access.log production; error_log /var/log/nginx/oss_proxy.error.log; # 動的 DNS 解決 (前の設定と同じ)。 resolver 100.100.2.136 100.100.2.138 valid=60s; # ヘルスチェックエンドポイント (前の設定と同じ)。 location /health { access_log off; return 200 "healthy"; } location / { # ... すべての proxy_* 設定は前の設定と同じです。 ... proxy_pass http://oss_backend; proxy_http_version 1.1; proxy_set_header Connection ""; # [必須] バケットの内部エンドポイントに置き換えてください。 proxy_set_header Host "your-bucket.oss-cn-hangzhou-internal.aliyuncs.com"; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; # X-Forwarded-Proto ヘッダーを追加して、クライアントが HTTPS を使用したことをバックエンドに伝えます。 proxy_set_header X-Forwarded-Proto $scheme; proxy_connect_timeout 10s; proxy_send_timeout 30s; proxy_read_timeout 30s; client_max_body_size 1024m; } } -
プロキシバッファの設定:大きなファイルの転送では、プロキシバッファリングを有効にしてメモリ使用量を最適化し、低速なクライアントによってバックエンド接続が保持され続けないようにします。location ブロックに以下を追加します。
location / { # ... その他の proxy_* 設定 ... # プロキシバッファリングを有効にし、バッファの数とサイズを設定します。 proxy_buffering on; proxy_buffers 8 128k; proxy_buffer_size 128k; proxy_busy_buffers_size 256k; } -
EIP の使用:安定したパブリック IP アドレスを確保するため、プロキシのエントリーポイント (SLB または ECS) に EIP をバインドします。
-
アクセスにドメイン名を使用:ドメイン名をプロキシ IP に紐付け、ドメイン経由でトラフィックを処理します。これにより、運用や将来の拡張が容易になります。
フォールトトレランス戦略
-
ヘルスチェック:ロードバランサーを設定して Nginx の
/healthエンドポイントをチェックし、障害が発生したインスタンスを自動的に切り離します。 -
タイムアウト設定:OSS の応答が遅い場合に接続が滞留するのを防ぐため、
proxy_connect_timeoutとproxy_read_timeoutを調整します。 -
リトライメカニズム:クライアントがサポートしている場合は、5xx エラーに対してアプリケーション層のリトライを実装します。
リスク防止
-
セキュリティ強化:セキュリティグループとネットワーク ACL で、必要な IP とポートのみを許可します。Web 攻撃から防御するために、プロキシの前に WAF をデプロイすることを検討してください。
-
監視とアラート:Nginx のログと主要なメトリクス (リクエストレイテンシー、エラーレート、CPU、メモリ、ネットワーク使用率) を監視します。これらのメトリクスにアラートのしきい値を設定します。
-
変更とロールバックの管理:デプロイ前に設定変更をテストします。迅速にロールバックできるよう履歴バージョンを保持します。
よくある質問
ブラウザでのファイルのプレビュー
OSS は、デフォルトのドメイン名でアクセスされた画像や Web ファイルをダウンロードさせる動作になります。ブラウザでファイルをプレビューするには、カスタムドメイン名をバケットに紐付け、それを Nginx 設定で使用します。「カスタムドメイン名を使用した OSS へのアクセス」をご参照ください。
403 Forbidden エラーのトラブルシューティング
403 エラーは通常、署名検証または権限の問題を示します。以下を確認してください。
-
Nginx 設定の確認:
proxy_set_header Hostディレクティブで設定された値が、バケットの内部エンドポイントと完全に一致することを確認します。 -
署名生成の確認:署名付き URL を生成する際、署名の計算に使用された
Hostヘッダーが、Nginx 設定のHostヘッダーと一致することを確認します。 -
バケット権限の確認:バケットポリシーまたは RAM ポリシーが必要な操作を許可しているかどうかを確認します。
-
ECS ロール承認の確認:アプリケーションが ECS インスタンス RAM ロールを使用して OSS にアクセスする場合、そのロールが対象のバケットに対する必要な権限を持っていることを確認します。
"413 Request Entity Too Large" のトラブルシューティング
Nginx は、アップロードされたファイルがサイズ制限を超えた場合にこのエラーを返します。server または location ブロックで client_max_body_size を増やし (たとえば、最大 2 GB の場合は client_max_body_size 2048m;)、Nginx をリロードします。
502 Bad Gateway エラーのトラブルシューティング
502 エラーは、Nginx が OSS から有効なレスポンスを取得できないことを意味します。考えられる原因は次のとおりです。
-
DNS 解決の問題:Nginx 設定に
resolverディレクティブが含まれていることを確認します。これがないと、Nginx はキャッシュされた古い IP アドレスを使用する可能性があります。 -
ネットワーク接続:ECS セキュリティグループとネットワーク ACL のアウトバウンドルールを確認します。OSS エンドポイントのポート 80 へのトラフィックが許可されていることを確認します。
-
不正なエンドポイント設定:
proxy_passとproxy_set_header Hostの OSS エンドポイントが正しいことを確認します。
1 つの Nginx で複数のバケットをプロキシする方法
Nginx の map ディレクティブを使用して、リクエストの Host ヘッダーに基づいてバックエンドバケットを動的に選択します。
# /etc/nginx/conf.d/multi_oss_proxy.conf
# Host ヘッダーを OSS の内部エンドポイントに動的に紐付けます。
map $http_host $oss_backend_host {
# [必須] a.example.com を bucket-a の内部エンドポイントに紐付けます。
"a.example.com" "bucket-a.oss-cn-hangzhou-internal.aliyuncs.com";
# [必須] b.example.com を bucket-b の内部エンドポイントに紐付けます。
"b.example.com" "bucket-b.oss-cn-shenzhen-internal.aliyuncs.com";
# デフォルト値。これは空にすることも、デフォルトのバケットを指定することもできます。
default "";
}
server {
listen 80;
# 複数のドメイン名でリッスンします。
server_name a.example.com b.example.com;
# ... その他の設定 (ロギング、リゾルバーなど) ...
location / {
# 紐付けの結果が空の場合は 404 を返します。
if ($oss_backend_host = "") {
return 404;
}
# proxy_pass と Host ヘッダーを動的に設定します。
proxy_pass http://$oss_backend_host;
proxy_set_header Host $oss_backend_host;
# ... その他の proxy_* 設定 ...
}
}