2 पॉइंट द्वारा GN⁺ 2024-06-02 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • AWS डेटा लीक के जोखिमों में S3 bucket पर unauthorized access बार-बार सामने आता है, और पुराने API design व exception जैसे व्यवहारों के कारण इसे सिर्फ “public/private” के रूप में आंकना मुश्किल है
  • कई S3 operations सामान्य AWS endpoint के बजाय bucket URL खुद पर call किए जाते हैं, और गलत bucket policy होने पर बिना authentication वाले curl request से भी जोखिम भरे operations संभव हो सकते हैं
  • सिर्फ s3:ListBucket block कर देने से सुरक्षित मानना मुश्किल है; ListBucketVersions, ListMultipartUploads, fetch-owner जैसे रास्ते object keys और account identifiers उजागर कर सकते हैं
  • uploader storage class, tags, Object Lock, और redirect से जुड़े कुछ headers जैसी object properties को प्रभावित कर सकता है, इसलिए IAM conditions और lifecycle policies जैसे अतिरिक्त controls की जरूरत होती है
  • केवल ACL और public access block settings देखकर bucket को private मान लेने पर कुछ access paths छूट सकते हैं; CloudFront distribution या Cognito identity pool के जरिए internet users S3 objects तक पहुंच सकते हैं

पुराने S3 API design और anonymous calls

  • S3, AWS की शुरुआती services में से एक है, इसलिए यह मजबूत और अच्छी तरह tested है, लेकिन standardized design patterns से पहले के निशानों के कारण अन्य AWS services से अलग API form रखता है
  • कुछ S3 APIs s3.us-east-2.amazonaws.com जैसे सामान्य endpoints इस्तेमाल करते हैं, लेकिन कई operations को target bucket URL पर सीधे request करना पड़ता है
    • bucket list query का उदाहरण Host: [bucketname].s3.amazonaws.com रूप में GET / है
    • bucket tags query भी उसी bucket host पर GET /?tagging भेजती है
  • EC2 या DynamoDB जैसी कई AWS services सामान्य endpoint इस्तेमाल करती हैं, और target resource को HTTP header या parameter के रूप में पास करना आम है
  • S3 buckets public access और authenticated access दोनों support करते हैं, इसलिए कौन-सा API operation बिना authentication के संभव है, यह हमेशा स्पष्ट नहीं होता
  • अगर example bucket policy bucket resource पर Principal: "*" और Action: "s3:*" allow करती है, तो बिना authentication वाले request से भी bucket delete करना संभव है
  • कुछ operations anonymous requests support नहीं करते, और s3:GetBucketOwnershipControls does not support Anonymous requests! जैसी error लौटती है
  • anonymous API requests CloudTrail में anonymous account के रूप में record होते हैं
    • अगर request unauthenticated है, तो यह identify नहीं किया जा सकता कि bucket किसने delete किया, या encryption settings अथवा logging status किसने query किया
  • /?logging, /?tagging, /?encryption जैसे paths browser में भी test किए जा सकते हैं
  • GetObjectTorrent जैसे operations भी हैं जिनके docs मौजूद हैं, लेकिन अब उन्हें execute नहीं किया जा सकता

सिर्फ ListBucket block करने से object key exposure रोकना मुश्किल है

  • S3 object download करने के लिए हर object की key चाहिए होती है, और key का उपयोग file path की तरह होता है
  • root bucket पर GET request कुछ conditions में bucket contents लौटा सकता है, इसलिए s3:ListBucket deny करना एक आम बचाव जैसा दिखता है
  • public-read ACL और s3:ListBucket deny policy साथ इस्तेमाल करने पर भी object keys पाने के रास्ते बचे रहते हैं
    • GET /?versions, यानी s3:ListBucketVersions, bucket के अंदर object versions का metadata लौटाता है
    • GET /?uploads, यानी s3:ListMultipartUploads, चल रहे multipart uploads की list लौटाता है
  • HeadBucket docs में bucket के existence और access permissions check करने से जुड़ी wording है, लेकिन व्यवहार में यह check करता है कि ListBucket operation करने की permission है या नहीं
  • केवल ListBucket deny है या नहीं, यह verify करने पर S3 object keys expose होने की संभावना छूट सकती है

अधूरे multipart upload की लागत और exposure

  • multipart upload create-multipart-upload से शुरू होता है और upload-part से parts upload किए जाते हैं
  • अधूरे multipart uploads को web console में देखना आसान नहीं है; इन्हें /?uploads या aws s3api list-multipart-uploads --bucket [bucket-name] से देखा जा सकता है
  • अगर completion request सफलतापूर्वक भेजी नहीं जाती, तो Amazon S3 parts को assemble नहीं करता और object भी नहीं बनाता
    • uploaded parts तब तक account में रहते हैं जब तक multipart upload complete या abort नहीं होता
    • stored parts पर S3 storage cost लगती है
  • complete होने से पहले object के parts download करने का तरीका नहीं मिला, लेकिन delete करना संभव है
  • AWS एक तय number of days के बाद अधूरे uploads delete करने वाली lifecycle rule apply करने की सिफारिश करता है
  • /?uploads से अधूरे multipart uploads list करने पर upload शुरू करने वाले principal का ARN लौटता है
    • अगर account ID, ARN जैसे identifiers को non-sensitive मानते हैं, तो यह problem नहीं हो सकती
    • अगर attacker के लिए उपयोगी identifiers reveal करना नहीं चाहते, तो इसे exposure माना जा सकता है

ACL और email-based account verification

  • S3 ACL docs में उस दौर के निशान बचे हैं जब AWS accounts को root user email से identify किया जाता था
  • PutBucketACL operation grantee को email address से specify कर सकता है
    • Type: AmazonCustomerByEmail और EmailAddress का उपयोग होता है
  • अगर दिए गए email से जुड़ा AWS account नहीं है, तो UnresolvableGrantByEmailAddress error आती है
    • error message इस तरह होता है कि “दिया गया email address records में किसी account से match नहीं करता”
  • इस behavior की वजह से यह check किया जा सकता है कि किसी खास email address के पास registered AWS account है या नहीं

uploader द्वारा चुनी जा सकने वाली storage class और object metadata

  • S3 की storage class bucket पर नहीं, object पर apply होती है
  • bucket level पर desired storage class fix करने की setting नहीं है, और upload करने वाला subject object की storage class specify कर सकता है
    • उदाहरण है aws s3 cp "my.txt" "s3://mybucket/myobject.txt" --storage-class [CLASS]
  • uploader predefined list के भीतर ऐसे विकल्प चुन सकता है जो bucket owner द्वारा वहन की जाने वाली per-GB storage और access costs को प्रभावित करें
  • IAM policy में s3:x-amz-storage-class condition key का उपयोग करके allowed storage classes को restrict किया जा सकता है
    • example policy s3:PutObject के लिए केवल STANDARD allow करती है
  • lifecycle policy set करने पर एक निश्चित अवधि के बाद सभी objects को किसी specific storage class में transition किया जा सकता है
  • pre-signed URL इस्तेमाल करने वाले uploads में AWS Signature Version 4 X-Amz- से शुरू होने वाले सभी headers की signing require करता है
    • storage class x-amz-storage-class header से specify होती है
    • अगर application बहुत गलत तरीके से implemented न हो, तो तुरंत manipulate करने का कोई साफ तरीका नहीं दिखता

tags, Object Lock, redirect भी uploader के प्रभाव में हैं

  • S3 objects से जुड़ी कई properties uploader control करता है
  • object tags upload के समय specify किए जा सकते हैं
    • उदाहरण है --tagging "AllYourTags=AreBelong&To=Us"
  • tag values के आधार पर automation करने वाले systems uploader द्वारा बनाए गए tag values से प्रभावित हो सकते हैं
  • Object Lock bucket में object locking enabled होने पर object retention और legal hold set कर सकता है
    • example command --object-lock-retain-until-date "2099-01-01T00:00:00+0000", --object-lock-legal-hold-status "ON", --object-lock-mode "COMPLIANCE" इस्तेमाल करता है
  • static website hosting enabled buckets में uploaded file settings का उपयोग करके open redirect संभव है
  • PutObject द्वारा support किए जाने वाले headers की पूरी list पर भी ध्यान देने की जरूरत है
    • pre-signed URL में limitations होती हैं
    • Cognito identity और IAM policy पर निर्भर configurations में authenticated Cognito context से request sign किया जा सकता है

bucket owner और account identifiers का exposure

  • यह confirm करने के लिए कि कोई specific account ID accessible bucket का owner है या नहीं, ListBucket request में x-amz-expected-bucket-owner header डाल सकते हैं
    • गलत account ID डालने पर AccessDenied लौटता है
    • सही account ID डालने और caller के पास ListBucket permission होने पर normal response लौटता है
  • ListBucket API के fetch-owner=true parameter का उपयोग करने पर response में हर key के लिए Owner element शामिल होता है
  • Owner के अंदर ID एक 64-character hexadecimal string है, जिसे AWS docs में canonical user ID कहा जाता है
    • यह AWS account ID का obfuscated form है
  • canonical user ID को IAM policy के Principal में CanonicalUser के रूप में डालकर save करने और फिर refresh करने पर यह AWS account ID में resolve हो जाता है
  • ListBucketVersions और ListMultipartUploads भी fetch-owner के बिना मिलते-जुलते तरीके से काम करते हैं

S3 object keys file names जैसी दिखती हैं, लेकिन अलग तरह से काम करती हैं

  • S3 object keys case-sensitive होती हैं
  • नाम एक जैसे दिखें, फिर भी uppercase/lowercase अलग होने पर कई objects upload किए जा सकते हैं
  • अगर application S3 object keys को case-insensitive file names की तरह handle करता है, तो समस्याएं हो सकती हैं
    • example application user passwords को S3 file में store करता है, और file name के रूप में username इस्तेमाल करता है
    • sign-up के समय केवल file existence check करता है, और password change के समय username को lowercase में बदलकर file में लिखता है
    • jeff पहले से होने पर भी JEFF sign-up कर सकता है, और JEFF user password change करके jeff की file overwrite कर सकता है
  • S3 object key में कोई भी UTF-8 character इस्तेमाल किया जा सकता है
    • कुछ characters कुछ applications और protocols में problem पैदा कर सकते हैं
    • spaces, slashes, percent characters आदि भी object key में valid हैं

“private bucket” जैसा दिखने पर भी access paths बचे हो सकते हैं

  • ACLs बंद हों, resource policy narrow set हो, और block public access enabled हो, फिर भी bucket publicly accessible हो सकता है
  • सबसे common path Amazon CloudFront distribution है
    • S3 bucket के आगे CDN रखने के मामलों में आम तौर पर internet content delivery का intent होता है
    • security tools bucket resource policy CloudFront तक limited होने पर इसे public नहीं मान सकते
  • example में get-bucket-policy-status IsPublic: false लौटाता है
    • bucket पर direct request करने पर AccessDenied लौटता है
    • CloudFront distribution domain पर वही request भेजने पर object content लौटता है
  • Cognito identity pool भी restricted resource policy वाले bucket को expose कर सकता है
    • Cognito login success के बाद pre-configured role के temporary AWS credentials देता है
    • अगर उस role के पास s3:ListBucket और s3:GetObject permissions हैं, तो user S3 API call कर सकता है
  • public access में आ सकने वाली Cognito settings दो तरह की हैं
    • Self-registration: अगर internet users app में sign up और login कर सकते हैं, तो यह effectively public access बन जाता है
    • Guest access: unauthenticated users को unique identifier और AWS credentials प्रदान करता है
  • guest access example का flow है: get-id से IdentityId लेना, get-credentials-for-identity से temporary credentials लेना, और फिर उस profile से aws s3 ls चलाना
  • CloudFront और Cognito identity pool वास्तव में internet पर अक्सर इस्तेमाल होते हैं, लेकिन security tools में ये public access paths कम ही दिखाए जाते हैं

1 टिप्पणियां

 
GN⁺ 2024-06-02
Hacker News राय
  • दिलचस्प बातें तो कई हैं, लेकिन फ़ाइल सिस्टम के case-sensitive होने को शिकायत की वजह मानने से सहमत होना मुश्किल है
    मेरे हिसाब से उसे ऐसा ही होना चाहिए, और macOS का ऐसा न करना उल्टा परेशान करता है

    • “उसे ऐसा ही होना चाहिए” क्यों, यह समझ नहीं आता। Windows भी case-sensitive नहीं है, इसलिए S3 कोई लगभग सार्वभौमिक प्रथा नहीं तोड़ रहा
      फ़ाइल नामों में case-sensitivity non-technical users को भी अप्रत्याशित लग सकती है। अगर कोई कहे कि उसने “Book Draft 1.docx” भेजा है, लेकिन mailbox में “Book draft 1.docx” हो, तो आमतौर पर कोई यह नहीं कहेगा, “लगता है आपने अलग फ़ाइल भेज दी?”
      लिखे हुए टेक्स्ट में भी case आम तौर पर अर्थ नहीं बदलता। “Hi, how are you?” और “hi, how are you?” का मतलब एक ही है, और uppercase से अर्थ बदलना ज़्यादातर proper noun और common noun में फ़र्क करने तक सीमित है, जो फ़ाइल नामों में शायद ही कोई मुख्य चिंता हो
    • तकनीकी implementation के लिहाज़ से 'A' और 'a' अलग characters हैं, यह ASCII, Unicode आदि में अच्छी तरह स्थापित है
      निजी पसंद अलग बात है, लेकिन किसी developer या system administrator का फ़ाइल सिस्टम की case-sensitivity देखकर चौंकना या चिढ़ना समझना मुश्किल है। ज़रूरत हो तो developers इसे end users के लिए abstract कर सकते हैं, जैसे search results में होता है
    • मैं लेखक हूँ। यह शिकायत से ज़्यादा observation है। यह बिल्कुल अच्छा/बुरा होने का मामला नहीं, बल्कि application design करते समय ध्यान रखने वाली चीज़ है
    • मुझे ठीक-ठीक समझ नहीं आता कि फ़ाइल नामों के case-sensitive होने से फायदा क्या है। उल्टा होने पर ऐसी कई आम गलतियाँ शुरू से हो ही नहीं सकतीं
      यह coding जैसा भी नहीं है, जहाँ code style enforce करने से readability में मदद मिलती है। Programming में भी, IDEs के variable name typos पकड़ने लायक smart होने से पहले, यह bugs की वजह बनता था। Pascal की एक अच्छी बात यह थी कि C के उलट case की चिंता नहीं करनी पड़ती थी
    • macOS case-preserving तो है। निजी तौर पर मुझे यह दोनों तरफ़ के फायदे अच्छी तरह मिलाने वाला तरीका लगता है
      आप फ़ाइल नाम अपनी पसंद के style में लिख सकते हैं और वह spelling बची रहती है, लेकिन search या processing करते समय आपको वह style ठीक-ठीक याद रखने की ज़रूरत नहीं होती। क्योंकि search case-sensitive नहीं होता
  • case-sensitivity तो आसान हिस्सा है; ज़्यादा कम intuitive बात यह है कि S3 paths नकली होते हैं
    S3 “/builds/1/installer.exe” upload स्वीकार कर लेता है और /builds के अंदर की listing भी दिखा देता है, लेकिन असल में आपने नाम में '/' शामिल रखने वाली '/builds/1/installer.exe' नाम की एक key upload की होती है
    इसलिए “/builds/1//installer.exe” और “/builds//1/installer.exe” भी upload किए जा सकते हैं और वे पूरी तरह अलग फ़ाइलें हैं। वे सिर्फ़ key names हैं; असली directories नहीं हैं

    • सही। हालांकि अगर नए S3 Directory buckets [1] इस्तेमाल करें तो यह exception है, और यही पूरी चीज़ को और confusing बना देता है
      [1] https://docs.aws.amazon.com/AmazonS3/latest/userguide/direct...
    • यह भी नहीं भूलना चाहिए कि "/" बस default path delimiter character है। अगर फ़ाइल नाम में "/" चाहिए, तो delimiter के लिए अपनी पसंद का कोई दूसरा character इस्तेमाल कर सकते हैं: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObje...
    • paths को किसी standard form में interpret करने, जैसे duplicate / को merge करने, के अलावा real directory prefix से मूल रूप से कैसे अलग है, यह समझ नहीं आता
    • prefix वाला तरीका सच में बहुत सारे bugs बनाता है। AWS ने ऐसा क्यों किया, यह समझ आता है और वास्तव में यह smart approach है, लेकिन फिर भी बहुत से developers इसमें फँस जाते हैं
      इस साल हमारे production system में भी एक अजीब bug आया और 5 लोगों के लगने के बाद ही मिला। कारण एक object था जिसका नाम literal तौर पर “/” था, और software उसे file नहीं बल्कि path की तरह handle करने की कोशिश कर रहा था
  • S3 या दूसरे AWS services पर भरोसा करके इस्तेमाल करना मुश्किल है। कुछ भी intuitive नहीं है, moving parts बहुत ज़्यादा हैं, और पढ़ने के लिए documentation भी बहुत है
    इतना करने पर भी, मूल लेख जैसी गलती से सब कुछ पूरी दुनिया के लिए public कर सकते हैं। मैं इसके बजाय Hetzner Storage Boxes या DigitalOcean Spaces जैसी सचमुच सरल services इस्तेमाल करूँगा

    • मुझे DigitalOcean Spaces पसंद है, लेकिन वहाँ भी परेशान करने वाली quirks हैं
      हाल ही में पता चला कि कुछ MB से बड़े video files को pipe करके upload करने पर returned Location में https:// छूट जाता है। इसलिए हर file upload पर check करना पड़ता है कि Location https से शुरू होता है या नहीं, और न हो तो जोड़ना पड़ता है
      जाहिर है, S3 Node client के GitHub issue में कहते हैं “लगता है DigitalOcean bug है”, और DigitalOcean forum में कहते हैं “लगता है S3 Node client bug है”
    • DigitalOcean जिस तरह secrets handle करता है, वह किसी को भी डरा सकता है। Container Registry इस्तेमाल करते हुए अगर K8S को automatic access के लिए configure करें, तो क्या आपको पता था कि वह service ऐसा secret बनाती है जिसे Spaces का full access होता है?
    • कई साल cloud development से दूर रहकर ज़्यादातर client-side काम करने के बाद हाल में लौटा, और इस बीच जमा हुई complexity और public cloud में लोहे जैसा मजबूत solution बनाने के लिए ज़रूरी cognitive load देखकर हैरान रह गया
      ढेरों features और quirks, जिन्हें मूल रूप से कुछ special cases में मदद के लिए design किया गया था, अब general protocol का हिस्सा बन गए हैं। लगता है business के लिहाज़ से किसी को भी दूर न करने की कोशिश में ऐसा हुआ है
  • अरबों objects हटाते समय भी सावधानी बरतनी चाहिए। delete API को सीधे call करना महंगा पड़ सकता है
    इसके बजाय wildcard या पूरे bucket के लिए expiry time को now सेट करने वाला lifecycle rule मुफ्त में configure किया जा सकता है। तब storage billing तुरंत रुक जाती है और AWS deletion को अपने-आप संभालता है

    • सख्ती से कहें तो delete calls मुफ्त हैं; लागत list query calls की होती है, जो objects पाने के लिए करनी पड़ती हैं। सिद्धांततः अगर आपको किसी दूसरी source से पता है कि कौन-से objects मौजूद हैं, तो यह मुफ्त है
    • lifecycle rule का असर तुरंत नहीं होता। यह दिन में एक बार चलने वाले batch job के रूप में लागू होता है, इसलिए removal तुरंत नहीं होता
    • क्योंकि AWS असल deletion timing चुन सकता है। metadata में object को deleted के रूप में mark कर देता है, और AWS कम usage वाले समय में deletion process कर सकता है
      इससे S3 API servers पर प्रति सेकंड requests की मार पड़ने से भी बचा जा सकता है
  • असफल multipart uploads का अदृश्य रूप से बचे रहना, और अगर आपने स्पष्ट रूप से lifecycle setting नहीं की तो उन पर storage cost लगना, सच में बहुत खराब है
    मुझे लगा था “Simple” में S का मतलब simplicity है

    • सही है, वह खराब है। इसके लिए उस समय S3 GM रहे ahenry@ को दोष दें
      मेरा प्रस्ताव था कि incomplete uploads के parts आखिरी activity के बाद सिर्फ 24 घंटे रहें, और उस दौरान storage cost भी charge न की जाए। ahenry@ ने इसे reject कर दिया
    • इस समस्या में हमने हजारों dollars गंवा दिए
      एक बहुत पुराने server पर लगभग 10 साल तक हर रात multipart upload शुरू करने वाली cron script चल रही थी। इसका काम backups को bucket में push करना था, लेकिन उसी bucket में user-uploaded content भी store होता था, इसलिए उसका रोज थोड़ा-थोड़ा बढ़ना सामान्य लगता था
      script “काम नहीं कर रही” थी, इसलिए हम backup data पर निर्भर नहीं थे; S3 में भी files नहीं दिखती थीं; और bucket size लगातार, लेकिन बहुत ज्यादा नहीं, बढ़ रहा था। लेकिन इस spring में देखा तो करीब 3TB incomplete multipart uploads store हो रहे थे
      जाहिर है, मुझे पता है कि यह किस्सा खराब practices से भरा है
    • वह S खर्च बढ़ाने के Simple तरीके का S है
    • “Simple” नाम उस समय रखा गया था जब विकल्प था disks लगे servers के झुंड को खुद manage करना। समय सब कुछ बदल देता है
    • मैंने भी storage cost की landmine पर पैर रखा है। शुक्र है, वह कुछ cents ही था, लेकिन console जिस तरह संबंधित जानकारी दिखाता है वह इतना घटिया है कि काफी गुस्सा आता है
  • case-sensitive/case-insensitive वाली चर्चा कुल मिलाकर बहुत English-centric लगती है
    दूसरे शब्दों में, खासकर IT में language-related discussions अक्सर जरूरत से ज्यादा English-centric होती हैं

    • मेरे हिसाब से English-centric होना उल्टा अच्छी बात है। क्योंकि Unicode की तुलना में ASCII को handle करना कहीं आसान था
      non-native English speaker के तौर पर कहूं तो programming में पहले से ही बहुत सारे concepts और elements हैं। बेहतर है कि इसमें 101 अलग-अलग languages को ध्यान में रखकर complexity और न बढ़ाई जाए
      Unicode और time zones programming में ज्यादा languages और cultures को ध्यान में रखने की कोशिश के प्रमुख examples हैं, और नतीजे में वे non-English programmers समेत सभी के लिए सबसे बड़ा दर्द बनते हैं
      मैं अपनी मातृभाषा में programs लिखना नहीं चाहता। अगर इसके बदले programming करते समय सारी major languages को ध्यान में रखना पड़े, तो और भी नहीं। IT discussions का English-centric होना ठीक है। diversity complexity है, और English कोई ऐसी भाषा नहीं है जिसका मालिक कोई एक हो; यह बस एक tool है जिसे लोग communication के लिए इस्तेमाल करते हैं
      उसी common language की वजह से मैं India, China, Japan, South America आदि के कई लोगों तक अपने विचार पहुंचा सकता हूं। जिस क्षण वे English में बोलने का फैसला करते हैं, वे भी English के मालिक हो जाते हैं। IT में diversity politics खींचकर लाने की जरूरत नहीं; इसे technical रखना बेहतर है
    • non-English cultures की बात चली है तो, Japanese में case-insensitive systems क्या hiragana और katakana में फर्क करते हैं?
      एक तरह से ये दो syllabaries uppercase/lowercase alphabets जैसी महसूस होती हैं
  • कुछ और बातें भी हैं
    मल्टीपार्ट अपलोड instance credentials वाले कई मशीनों से नहीं किया जा सकता। वजह यह है कि principals अलग होते हैं, इसलिए वे एक-दूसरे के multipart upload तक access नहीं कर सकते। कई मशीनों से एक multipart upload assemble करना हो तो वास्तविक IAM user चाहिए
    LIST requests सिर्फ धीमी ही नहीं, बड़े पैमाने पर बहुत महंगी भी होती हैं। “bucket inventory” जैसे workarounds हैं, लेकिन वे न तो सुविधाजनक हैं और न ही सस्ते
    bucket creation अंदरूनी तौर पर DNS का इस्तेमाल करता है, इसलिए write-after-read consistency नहीं होती। इसलिए कभी-कभी bucket बनाने के तुरंत बाद उसे access नहीं किया जा सकता, या changes propagate होने के लिए पर्याप्त इंतजार करने से पहले अभी-अभी बनाए गए bucket को delete नहीं किया जा सकता। https://github.com/julik/talks/blob/master/euruko-2019-no-su... देखें
    “foo” नाम का object और “foo/bar” नाम का object एक साथ बनाए जा सकते हैं। तब ऐसी संरचना बन जाती है जहां एक file directory को overwrite कर देती है, और bucket data को filesystem structure में port करना असंभव हो जाता है
    S3 case-sensitive है, इसलिए ऐसे objects बनाए जा सकते हैं जिन्हें filesystem structure में port नहीं किया जा सकता। Rails file storage ने case-sensitive storage मान लिया था, इसलिए macOS पर बुरी तरह टूट गया, और बाद में identifiers को हमेशा lowercase में लिखने के लिए fix किया गया
    अधिकतर S3 configurations GET की अनुमति देती हैं, लेकिन HEAD की नहीं। लगता है यह object existence probing रोकने का तरीका है, हालांकि पक्का नहीं। किसी भी हाल में, HEAD request से object size जांचने वाला cache-friendly flow, खासकर pre-signed URL में, काम नहीं करता। इसके बजाय बहुत छोटा Range लगाकर GET करना पड़ता है, जैसे सिर्फ पहला byte लाना
    अगर आप बहुत सारे pre-signed URLs generate करते हैं, तो generation speed 10–40 गुना बढ़ाने की संभावना है: https://github.com/WeTransfer/wt_s3_signer
    अधूरे multipart uploads की storage cost भी फिर भी देनी पड़ती है। अगर आपकी संरचना में users ऐसे uploads शुरू कर सकते हैं, तो खास सावधान रहना चाहिए। एक setting है जो कुछ समय बाद अधूरे multipart uploads को automatically delete कर देती है; परेशानी से बचना हो तो उसे enable करना चाहिए
    विडंबना यह है कि S3 क्रांतिकारी था और आज भी कई स्तरों पर शानदार product है। बस, features जितने ज्यादा हैं, pitfalls भी उतने ही ज्यादा हैं

    • कुछ हफ्ते पहले जिसने मुझे अटकाया, वह multipart upload की minimum initial chunk size 5MiB limit थी: https://docs.aws.amazon.com/AmazonS3/latest/userguide/qfacts...
      Elixir में Stream.transform(https://hexdocs.pm/elixir/Stream.html#transform/3) का इस्तेमाल करके columns को modify और inject करने वाली streaming CSV post-processing pipeline बनाई थी। Elixir के AWS और CSV modules incoming streaming data को तो process करते हैं, लेकिन outgoing stream का total size 5MiB से छोटा हो तो AWS module multipart upload इस्तेमाल करता है, इसलिए S3 में error आती थी—दुखद था
  • एक और दिलचस्प problem है, जिसे मैंने एक colleague के साथ कई दिनों तक analyze करके diagnose किया। S3 किसी single TCP connection से 100 HTTP requests भेजे जाने के बाद आगे की requests को चुपचाप drop कर देता है
    https://github.com/aws/aws-sdk-go/issues/2825

    • चुपचाप drop नहीं करता; वह TCP connection बंद किए जाने का header भेजता है
      performance के लिए keep-alive चाहिए, लेकिन client बहुत लंबे समय तक जुड़ा रहकर load balancer पर hotspot न बनाए—ऐसे मामलों में यह common pattern है
  • यह बात भी है कि standard storage class में S3 की latency ज्यादा है, इसलिए यह web serving के लिए उपयुक्त नहीं है
    कई लोग सोचते हैं कि images या fonts जैसे website resources सीधे S3 से host कर देना ठीक है, लेकिन user experience खराब हो सकता है
    “applications can achieve consistent small object latencies (and first-byte-out latencies for larger objects) of roughly 100–200 milliseconds.”
    स्रोत: https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimi...

    • अधिकतर लोग content delivery के लिए S3 को AWS CloudFront के origin के रूप में इस्तेमाल करते हैं
      CloudFront signed cookies का इस्तेमाल करके किसी specific user को S3 में उसके अपने content तक ही CDN access भी दिया जा सकता है। काफी बढ़िया है
    • web assets serve करने के लिए आम तौर पर S3 और CloudFront साथ में इस्तेमाल किए जाते हैं
      frequently accessed assets को cache करके latency घटाई जा सकती है, और cost भी काफी कम हो सकती है
    • S3 website को सीधे serve करने के लिए optimized नहीं है; यह लगभग unlimited data को durably store और retrieve करने के लिए optimized है
  • uploader द्वारा rules तय किया जाना काफी rough है। अगर कोई website की configuration कमजोर हो, तो क्या इसका मतलब है कि पर्याप्त motivation वाला user user content को Amazon Glacier में upload करवा सकता है, और बाद में वहीं से serve भी करवा सकता है?