Rails+Paperclip迁移Cloudfront后无法上传图片求助
我有一个使用Paperclip对接AWS的旧Rails应用,因TLS兼容性问题迁移至Cloudfront,但遇到图片上传失败问题。图片可正常获取且使用正确的Cloudfront URL,模型配置如下:
has_attached_file :image, :storage => :s3, :s3_credentials => "#{RAILS_ROOT}/config/s3.yml", :path => "images/:attachment/:id/:style.:extension", :url => ':s3_alias_url', :s3_host_alias => 'XXX.cloudfront.net', :styles => { :large => {:geometry => "3500x3500>", :processors => [:cropper]}, :medium => {:geometry => "512x512>", :processors => [:cropper]}, :thumb => {:geometry => "160x160>", :processors => [:cropper]} }
但上传时出现错误,日志显示仍连接s3.amazonaws.com,报错信息如下:
Processing Admin::ImagesController#create (for 24.154.30.187 at 2023-11-03 01:39:51) [POST] Parameters: {"controller"=>"admin/images", "commit"=>"Upload Images", "property_id"=>"15948", "action"=>"create", "image"=>{"image"=>[#<File:/tmp/RackMultipart20231103-1151-c5g19p-0>, #<File:/tmp/RackMultipart20231103-1151-y1vfa4-0>], "caption"=>""}} [paperclip] Saving attachments. [paperclip] saving images/images/467324/thumb.jpg New RightAws::S3Interface using shared connections mode Opening new HTTPS connection to s3.amazonaws.com:443 ##### RightAws::S3Interface returned an error: 403 Forbidden <?xml version="1.0" encoding="UTF-8"?> <Error><Code>InvalidTlsVersion</Code><Message>Amazon S3 will stop supporting TLS 1.0 and TLS 1.1 connections. Please update your client to use TLS version 1.2 or above. To learn more and to update your client, see https://go.aws/3AUlVSb. For further assistance, contact AWS suppo$ ##### RightAws::S3Interface request: https://s3.amazonaws.com:443/ #### Closing HTTPS connection to s3.amazonaws.com:443, reason: 'RightAws::AWSErrorHandler: code: 403: 'Forbidden'' RightAws::AwsError (InvalidTlsVersion: Amazon S3 will stop supporting TLS 1.0 and TLS 1.1 connections. Please update your client to use TLS version 1.2 or above. To learn more and to update your client, see https://go.aws/3AUlVSb. For further assistance, contact AWS support.): /home/ubuntu/.rvm/gems/ruby-1.8.7-p371@vires/gems/right_aws-3.0.4/lib/awsbase/right_awsbase.rb:562:in `request_info_impl' /home/ubuntu/.rvm/gems/ruby-1.8.7-p371@vires/gems/right_aws-3.0.4/lib/s3/right_s3_interface.rb:203:in `request_info' /home/ubuntu/.rvm/gems/ruby-1.8.7-p371@vires/gems/right_aws-3.0.4/lib/s3/right_s3_interface.rb:240:in `create_bucket' /home/ubuntu/.rvm/gems/ruby-1.8.7-p371@vires/gems/right_aws-3.0.4/lib/s3/right_s3.rb:103:in `bucket' vendor/plugins/paperclip/lib/paperclip/storage.rb:163:in `s3_bucket' vendor/plugins/paperclip/lib/paperclip/storage.rb:199:in `flush_writes' vendor/plugins/paperclip/lib/paperclip/storage.rb:195:in `each' vendor/plugins/paperclip/lib/paperclip/storage.rb:195:in `flush_writes' vendor/plugins/paperclip/lib/paperclip/attachment.rb:141:in `save' vendor/plugins/paperclip/lib/paperclip.rb:331:in `send' vendor/plugins/paperclip/lib/paperclip.rb:331:in `save_attached_files' vendor/plugins/paperclip/lib/paperclip.rb:324:in `each_attachment' vendor/plugins/paperclip/lib/paperclip.rb:323:in `each' vendor/plugins/paperclip/lib/paperclip.rb:323:in `each_attachment' vendor/plugins/paperclip/lib/paperclip.rb:330:in `save_attached_files' activesupport (2.3.2) lib/active_support/callbacks.rb:178:in `send' activesupport (2.3.2) lib/active_support/callbacks.rb:178:in `evaluate_method' activesupport (2.3.2) lib/active_support/callbacks.rb:166:in `call' activesupport (2.3.2) lib/active_support/callbacks.rb:93:in `run' activesupport (2.3.2) lib/active_support/callbacks.rb:92:in `each' activesupport (2.3.2) lib/active_support/callbacks.rb:92:in `send' activesupport (2.3.2) lib/active_support/callbacks.rb:92:in `run' activesupport (2.3.2) lib/active_support/callbacks.rb:276:in `run_callbacks' activerecord (2.3.2) lib/active_record/callbacks.rb:344:in `callback' activerecord (2.3.2) lib/active_record/callbacks.rb:251:in `create_or_update' activerecord (2.3.2) lib/active_record/base.rb:2539:in `save_without_validation' activerecord (2.3.2) lib/active_record/validations.rb:1009:in `save_without_dirty' activerecord (2.3.2) lib/active_record/dirty.rb:79:in `save_without_transactions' activerecord (2.3.2) lib/active_record/transactions.rb:229:in `send' activerecord (2.3.2) lib/active_record/transactions.rb:229:in `with_transaction_returning_status' activerecord (2.3.2) lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction' activerecord (2.3.2) lib/active_record/transactions.rb:182:in `transaction' activerecord (2.3.2) lib/active_record/transactions.rb:228:in `with_transaction_returning_status' activerecord (2.3.2) lib/active_record/transactions.rb:196:in `save' activerecord (2.3.2) lib/active_record/transactions.rb:208:in `rollback_active_record_state!' activerecord (2.3.2) lib/active_record/transactions.rb:196:in `save' app/controllers/admin/images_controller.rb:28:in `create' app/controllers/admin/images_controller.rb:26:in `each' app/controllers/admin/images_controller.rb:26:in `create'
此前上传的图片可显示正确的Cloudfront URL:https://XXX.cloudfront.net/images/images/XXX/thumb.jpg?2023?1698977169
请问我遗漏了什么配置?
你的核心问题不是Cloudfront配置,而是上传时使用的AWS SDK(right_aws)版本过低,不支持TLS 1.2,导致连接S3时被拒绝。以下是具体修复步骤:
1. 明确Cloudfront的作用
Cloudfront只是S3的CDN分发层,上传操作仍然直接走S3 API,Cloudfront不处理文件上传。你配置的:s3_host_alias和:url => ':s3_alias_url'只影响图片的访问URL,不改变上传的目标地址。
2. 修复TLS兼容性问题
你的right_aws-3.0.4版本太老,Ruby 1.8.7默认的OpenSSL版本可能也不支持TLS 1.2。需要做以下调整:
方案A:升级right_aws版本
找到支持TLS 1.2的right_aws版本,比如更新到3.1.0及以上(需确认兼容Ruby 1.8.7),修改Gemfile后执行bundle update right_aws。方案B:强制OpenSSL使用TLS 1.2
如果无法升级gem,可以在初始化代码中强制指定TLS版本。在config/initializers/paperclip.rb中添加:require 'openssl' OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ssl_version] = :TLSv1_2方案C:升级Ruby版本(推荐)
Ruby 1.8.7早已停止维护,其配套的OpenSSL库对TLS 1.2的支持有限。如果可能,升级到Ruby 2.3及以上版本,从根本解决兼容性问题。
3. 额外检查S3配置
确保你的S3凭证文件(config/s3.yml)中指定了正确的区域,避免使用全局的s3.amazonaws.com,改用区域特定的端点(比如us-east-1对应s3.us-east-1.amazonaws.com),这也能提升上传稳定性。
内容的提问来源于stack exchange,提问作者Sara Fuerst

