Access OSS through an ECS reverse proxy
OSS IP addresses change dynamically, which can break firewall allowlists or fixed-IP integrations. To access OSS through a stable IP, deploy an Nginx reverse proxy on an ECS instance with a fixed public IP (EIP).
How it works
ECS instances with fixed public IPs serve as traffic entry points. Nginx forwards requests to OSS as follows:
-
A client requests an OSS resource through the ECS instance's fixed public IP (EIP).
-
Nginx on the ECS instance receives the request.
-
Nginx forwards the request to the target OSS bucket.
-
OSS processes the request and returns the response to Nginx.
-
Nginx returns the response to the client.
Configure the ECS reverse proxy
Step 1: Create an ECS instance
Create an ECS instance to host the Nginx reverse proxy.
-
Create an ECS instance with the following settings. Use defaults for other parameters.
-
Payment Option: Select Pay-As-You-Go.
-
Region: Select the same region as the OSS bucket you want to proxy. This allows you to use the internal endpoint to reduce traffic costs.
-
Network and zone: Select the default VPC and availability zone.
-
Instance Type: Click All Instance Types, then search for and select
ecs.e-c1m2.large.NoteIf this instance type is sold out, select another instance type.
-
Image: Select Public Image > Alibaba Cloud Linux (Alibaba Cloud Linux 3.2104 LTS 64-bit).
-
System disk: Set the capacity of the ESSD Entry disk to 40 GiB.
-
Public IP: Select Assign Public IPv4 Address.
-
Bandwidth Billing: Select Pay-by-traffic to reduce costs.
-
Peak Bandwidth: Select 5 Mbps or higher.
-
Security group: Select Create Security Group, and under Open IPv4 Ports/Protocols, select HTTP (TCP:80) to open the Nginx listening port.
-
Logon Credentials: Select Custom Password, set the username to root, and create a Logon Password. Store the password securely.
-
Step 2: Configure the Nginx reverse proxy
Install Nginx on the ECS instance and configure the reverse proxy rules.
-
Install Nginx.
yum install -y nginx -
For easier management, create a separate configuration file in the
/etc/nginx/conf.d/directory, such asoss_proxy.conf.vi /etc/nginx/conf.d/oss_proxy.confCopy the following configuration template into the file and replace the placeholder values as indicated in the comments.
NoteWhen you access files through the bucket's internal endpoint, the browser forces a download instead of rendering inline. To enable inline previews, set the
Hostheader to a custom domain name mapped to the bucket.# Define the OSS backend and enable connection reuse for better performance. upstream oss_backend { # [Required] Replace with your bucket's internal endpoint. server your-bucket.oss-cn-hangzhou-internal.aliyuncs.com:80; # Recommended number of keep-alive connections. Adjust based on the number of concurrent requests. keepalive 64; } # Define a production-level log format that includes key information such as upstream response time. 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; # [Required] Replace with the public IP address of the ECS instance or a domain name that resolves to the IP address. server_name your_ecs_public_ip_or_domain; # Access log path and format. access_log /var/log/nginx/oss_proxy.access.log production; error_log /var/log/nginx/oss_proxy.error.log; # Use a dynamic DNS resolver to ensure that Nginx is aware of IP address changes in the OSS backend. resolver 100.100.2.136 100.100.2.138 valid=60s; # Health check endpoint for load balancers or monitoring systems. location /health { access_log off; return 200 "healthy"; } location / { # Proxy requests to the upstream OSS backend defined above. proxy_pass http://oss_backend; # Key setting: Ensure that HTTP/1.1 and keep-alive connections are active. proxy_http_version 1.1; proxy_set_header Connection ""; # Key setting: Set the Host header to the bucket's internal endpoint to ensure that Signature V4 validation is successful. # [Required] Replace with your bucket's internal endpoint. proxy_set_header Host "your-bucket.oss-cn-hangzhou-internal.aliyuncs.com"; # Forward the client's real IP address. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; # Set proxy timeout values. proxy_connect_timeout 10s; proxy_send_timeout 30s; proxy_read_timeout 30s; # The maximum size of file uploads. 0 indicates no limit. Set this value based on your business requirements. client_max_body_size 1024m; } }Save and exit the editor.
-
Check the syntax of the Nginx configuration file.
nginx -tIf the output includes
syntax is okandtest is successful, the configuration is valid. -
Start the Nginx service to apply the configuration.
systemctl start nginx
Verify the reverse proxy
Verify the proxy based on your bucket's access permissions.
Public-read and public-read-write buckets
In a browser, access http://ecs_public_ip/object_path. Replace ecs_public_ip with the ECS instance's public IP (from the ECS console) and object_path with the object's path in the bucket. For example, for dest.jpg in the exampledir directory, the object_path is exampledir/dest.jpg.
The browser accesses the dest.jpg file and opens your system's Save dialog box, allowing you to save the file to your computer.
Private buckets
Obtain a signed URL for the object from the console. For signature details, see Signature Version 4 (recommended).
-
Go to the Buckets list and click the target bucket.
-
For the object you want to access, click View Details in the Actions column.
-
Click Copy Object URL. In the copied URL, replace https with http, and replace the bucket domain name with the public IP address of your ECS instance.
-
Access the modified URL in your browser.
The browser opens a Save As dialog box for the file dest, which confirms that the signed URL has successfully accessed the private object and triggered a download.
Production recommendations
Apply the following practices to ensure stability, security, and cost-effectiveness in production.
Best practices
-
High-availability architecture: Use SLB with multiple ECS instances across availability zones to eliminate single points of failure.
-
Enable HTTPS: Enforce HTTPS to secure data in transit. Configure an SSL certificate for Nginx and redirect HTTP to HTTPS. Sample configuration:
NoteOpen port 443 in your ECS security group. Add, modify, or delete security group rules.
# ... The upstream and log_format configurations remain unchanged. ... # HTTP server block: Redirect all HTTP requests to HTTPS. server { listen 80; # [Required] Replace with the public IP address of the ECS instance or a domain name that resolves to the IP address. server_name your_ecs_public_ip_or_domain; # Redirect all HTTP requests to HTTPS by using a 301 redirect. return 301 https://$host$request_uri; } # HTTPS server block: Handle the actual proxy services. server { # Listen on port 443 for SSL connections. listen 443 ssl http2; # [Required] Replace with the public IP address of the ECS instance or a domain name that resolves to the IP address. server_name your_ecs_public_ip_or_domain; # --- SSL certificate configuration --- # [Required] Replace with the paths to your SSL certificate and private key files. ssl_certificate /path/to/your/fullchain.pem; ssl_certificate_key /path/to/your/private.key; # --- SSL security enhancement --- 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 path and format. access_log /var/log/nginx/oss_proxy.access.log production; error_log /var/log/nginx/oss_proxy.error.log; # Dynamic DNS resolution (same as in the previous configuration). resolver 100.100.2.136 100.100.2.138 valid=60s; # Health check endpoint (same as in the previous configuration). location /health { access_log off; return 200 "healthy"; } location / { # ... All proxy_* settings are the same as in the previous configuration. ... proxy_pass http://oss_backend; proxy_http_version 1.1; proxy_set_header Connection ""; # [Required] Replace with your bucket's internal endpoint. 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; # Add the X-Forwarded-Proto header to inform the backend that the client used 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; } } -
Configure proxy buffers: For large file transfers, enable proxy buffering to optimize memory usage and prevent slow clients from holding backend connections. Add the following to the location block:
location / { # ... other proxy_* configurations ... # Enable proxy buffering and set the number and size of buffers. proxy_buffering on; proxy_buffers 8 128k; proxy_buffer_size 128k; proxy_busy_buffers_size 256k; } -
Use an EIP: Bind an EIP to your proxy entry point (SLB or ECS) for a stable public IP address.
-
Use a domain name for access: Map a domain name to the proxy IP and serve traffic through the domain. This simplifies operations and future scaling.
Fault tolerance strategies
-
Health checks: Configure your load balancer to check Nginx's
/healthendpoint and automatically isolate failed instances. -
Timeout settings: Tune
proxy_connect_timeoutandproxy_read_timeoutto prevent connection buildup when OSS responses are slow. -
Retry mechanism: Implement application-layer retries for 5xx errors if your client supports it.
Risk prevention
-
Security hardening: In your security group and network ACL, allow only required IPs and ports. Consider deploying WAF in front of the proxy to defend against web attacks.
-
Monitoring and alerting: Monitor Nginx logs and key metrics (request latency, error rate, CPU, memory, network utilization). Set alert thresholds for these metrics.
-
Change and rollback management: Test configuration changes before deployment. Keep historical versions for quick rollbacks.
FAQ
Preview files in browser
OSS forces downloads for images and web files accessed through the default domain name. To preview files in the browser, map a custom domain name to the bucket and use it in your Nginx configuration. Access OSS by using a custom domain name.
Troubleshoot 403 Forbidden error
A 403 error usually indicates a signature validation or permission issue. Check the following:
-
Check the Nginx configuration: Make sure that the value set by the
proxy_set_header Hostdirective exactly matches the bucket's internal endpoint. -
Check the signature generation: When you generate the signed URL, confirm that the
Hostheader used to calculate the signature matches theHostheader in your Nginx configuration. -
Check the bucket permissions: Check whether the bucket policy or a RAM policy allows the required operations.
-
Check the ECS role authorization: If your application accesses OSS using an ECS instance RAM role, make sure that the role has the required permissions for the target bucket.
Troubleshoot 413 Request Entity Too Large
Nginx returns this error when the uploaded file exceeds the size limit. Increase client_max_body_size in the server or location block (for example, client_max_body_size 2048m; for up to 2 GB), then reload Nginx.
Troubleshoot 502 Bad Gateway error
A 502 error means Nginx cannot get a valid response from OSS. Possible causes:
-
DNS resolution issues: Ensure the Nginx configuration includes the
resolverdirective. Without it, Nginx may use a cached, outdated IP address. -
Network connectivity: Check your ECS security group and network ACL outbound rules. Ensure traffic to port 80 of the OSS endpoint is allowed.
-
Incorrect endpoint configuration: Verify that the OSS endpoint in
proxy_passandproxy_set_header Hostis correct.
Proxy multiple buckets with one Nginx
Use Nginx's map directive to dynamically select the backend bucket based on the request Host header.
# /etc/nginx/conf.d/multi_oss_proxy.conf
# Dynamically map the Host header to an OSS internal endpoint.
map $http_host $oss_backend_host {
# [Required] Map a.example.com to the internal endpoint of bucket-a.
"a.example.com" "bucket-a.oss-cn-hangzhou-internal.aliyuncs.com";
# [Required] Map b.example.com to the internal endpoint of bucket-b.
"b.example.com" "bucket-b.oss-cn-shenzhen-internal.aliyuncs.com";
# A default value. This can be left empty or can point to a default bucket.
default "";
}
server {
listen 80;
# Listen on multiple domain names.
server_name a.example.com b.example.com;
# ... Other settings such as logging, resolver, etc. ...
location / {
# If the mapped result is empty, return 404.
if ($oss_backend_host = "") {
return 404;
}
# Dynamically set the proxy_pass and Host header.
proxy_pass http://$oss_backend_host;
proxy_set_header Host $oss_backend_host;
# ... other proxy_* configurations ...
}
}