【问题标题】:Regex for s3 bucket names3 存储桶名称的正则表达式
【发布时间】:2018-05-23 06:06:19
【问题描述】:

我正在尝试通过 cloudformation 创建一个 s3 存储桶。我尝试使用正则表达式 ^([0-9a-z.-]){3,63}$,但它也接受根据新的 s3 命​​名约定无效的模式“...”和“---”。 (参考:https://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html)请帮忙?

【问题讨论】:

  • 对我来说,这些规则看起来既复杂又凌乱。为什么需要验证 S3 存储桶名称?您是否允许您的用户直接创建存储桶?
  • 允许使用哪些名称? 3-63 个字符 [0-9a-z.-] 除了两个名字,... 和 --- ? .., ...., --, ---, ..- 之类的名称是否允许?
  • @user31264 名称应以小写字母或数字开头和结尾。您可以在中间使用连字符
  • @TimBiegeleisen 是的,用户正在使用 cloudformation 创建存储桶。
  • @FellowBeginner 请注意,尽管存储桶名称允许包含点,但我强烈建议不要这样做。存储桶名称中有许多涉及点的“陷阱”,包括无法在存储桶上启用 S3 Transfer Acceleration,以及如果您根本不使用点就可以轻松避免的 HTTPS 证书问题。如果您在启动堆栈时让其他用户编造存储桶名称,他们可能不知道这些怪癖。

标签: json regex amazon-s3


【解决方案1】:

规格有点混乱,但主要标准似乎是这些:

  • 存储桶名称的长度必须至少为 3 且不超过 63 个字符。
  • 存储桶名称必须是一系列一个或多个标签。
  • 存储桶名称可以包含小写字母、数字和连字符。
  • 每个标签都必须以小写字母或数字开头和结尾。
  • 相邻标签由一个句点 (.) 分隔
  • 存储桶名称不得格式化为 IP 地址(例如 192.168.5.4)

如果是这样,那么这个正则表达式应该匹配:

(?=^.{3,63}$)(?!^(\d+\.)+\d+$)(^(([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\.)*([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])$)

第一组(?=^.{3,63}$) 向前看,以确保匹配长度在 3 到 63 个字符之间。

下一组(?!^(\d+\.)+\d+$) 提前禁止匹配看起来像 IP 地址的存储桶名称。

最后一组 (^(([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\.)*([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])$) 匹配零个或多个标签,后跟一个点 (([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\.)*,紧跟一个标签 ([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])

【讨论】:

  • 您好,感谢您的回复。这里的一个小问题是,当我尝试在这里转义反斜杠时(我使用的是 JSON),它不接受像 a.b.c 这样的模式。我使用了以下模式: (?=^.{3,63}$)(?!^(\\d+\\.?)+$)(^(([a-z0-9]|[a-z0 -9][a-z0-9\\-]*[a-z0-9])\\.)*([a-z0-9]|[a-z0-9][a-z0-9\ \-]*[a-z0-9])$)
  • 另外,它不匹配像 1000 这样的模式(基本上任何只包含数字的名称)
  • 不用担心。正则表达式在这里测试时有效:regex101.com/r/iPX9o6/1 - 所以,我猜这是一个逃避问题。如果^\\.$ 匹配单个. 并且不匹配其他任何东西,也许试试?
  • @FellowBeginner 我已经更新了负前瞻 (?!^(\d+\.)+\d+$) 以允许使用简单的数字序列。
【解决方案2】:

我稍微修改了 Zak 的回答。我发现它有点太复杂了,并抛出了有效的域名。这是新的正则表达式(可在 regex101.com** 上进行测试):

(?!^(\d{1,3}\.){3}\d{1,3}$)(^[a-z0-9]([a-z0-9-]*(\.[a-z0-9])?)*$)

第一部分是否定的前瞻(?!^(\d{1,3}\.){3}\d{1,3}$),它只匹配有效的IP 地址。基本上,我们尝试匹配 1-3 个数字,后跟 3 个句点 (\d{1,3}\.){3}),然后是 1-3 个数字 (\d{1,3})。

第二部分表示名称必须以小写字母或数字 (^[a-z0-9]) 开头,后跟小写字母、数字或连字符重复 0 到多次 ([a-z0-9-]*)。如果有句点,则后面必须跟一个小写字母或数字 ((\.[a-z0-9])?)。最后两种模式重复 0 到多次 (([a-z0-9-]*(\.[a-z0-9])?)*)。

正则表达式不会尝试强制执行 AWS 规定的大小限制(3-63 个字符)。这可以由另一个正则表达式 (.{3,6}) 或通过检查字符串的大小来处理。


** 在那个链接上,我添加的一个测试失败了,但是如果你切换到测试区域并输入相同的模式,它就会通过。如果您将其复制/粘贴到终端中,它也可以工作,所以我认为这是 regex101.com 方面的错误。

【讨论】:

  • 我修改了@c1moore 回答以包含以下条件:存储桶名称不能包含下划线、以破折号结尾、有连续句点或在句点旁边使用破折号。 docs.aws.amazon.com/awscloudtrail/latest/userguide/…(?!^(\d{1,3}\.){3}\d{1,3}$)(^[a-z0-9]([a-z0-9-]*(\.[a-z0-9])?)*$(?<!\-))
  • 这个似乎允许名称末尾的破折号
  • 你说得对,很好。我不确定这是否是创建此正则表达式时的要求。不过,@jophine 似乎对此有解决方案。
【解决方案3】:

S3 存储桶名称的正则表达式:

String S3_REPORT_NAME_PATTERN = "[0-9A-Za-z!\\-_.*\'()]+";

String S3_PREFIX_PATTERN   = "[0-9A-Za-z!\\-_.*\\'()/]*";

String S3_BUCKET_PATTERN = "(?=^.{3,63}$)(?!^(\\d+\\.)+\\d+$)(^(([a-z0-9]|[a-z0-9][a-z0-9\\-]*[a-z0-9])\\.)*([a-z0-9]|[a-z0-9][a-z0-9\\-]*[a-z0-9])$)";

【讨论】:

    【解决方案4】:

    如果您不想在存储桶名称中允许.(这是建议,否则无法启用 Transfer Acceleration),以下正则表达式符合 AWS 规范:

    ^((?!xn--)(?!.*-s3alias)[a-z0-9][a-z0-9-]{1,61}[a-z0-9])$
    

    这很好,因为它允许将^$ 简单地替换为其他字符串,从而允许ARN 检查等等。

    编辑: 根据@ryanjdillon 的评论添加了-s3alias 排除

    【讨论】:

    • 这个正则表达式不允许使用点 .,但它允许使用 -s3alias 的后缀。更新版本:^(?P<bucket_name>(?!xn--)(?!.*-s3alias)[a-z0-9][a-z0-9.-]{1,62}[a-z0-9])$。根据AWS bucket naming rules
    • 事实上我写道它的意图是不允许点......因为它们已被弃用。 +1 for -s3alias(我猜最近已经引入)
    【解决方案5】:

    我使用了@Zak 正则表达式,但它不是 100% 正确的。我使用 this 作为 AWS 存储桶名称的所有规则。我一步一步进行验证,所以它看起来像这样:

    • 存储桶名称的长度必须至少为 3 且不超过 63 个字符 -> ^.{3,63}$
    • 存储桶名称不能包含大写字符或下划线 -> [A-Z_]
    • 存储桶名称必须以小写字母或数字开头 -> ^[a-z0-9]
    • bucket 名称不得格式化为 IP 地址(例如 192.168.5.4)->^(\d+\.)+\d+$。这比 AWS 更受限制。
    • 存储桶名称必须是一系列一个或多个标签。相邻标签由单个句点 (.) 分隔 -> 在 python 中 if ".." in bucket_name:
    • ..每个标签必须以小写字母或数字结尾->^(.*[a-z0-9]\.)*.*[a-z0-9]$

    【讨论】:

      【解决方案6】:
      var bucketRGEX =  new RegExp(/(?=^.{3,63}$)/);
      var bucketRGEX1 =  new RegExp(/(?!^(\d+\.)+\d+$)/);
      var bucketRGEX2 =  new RegExp(/(^(([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\.)*([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])$)/);
      var result = bucketRGEX.test(bucketName);
      var result1 = bucketRGEX1.test(bucketName);
      var result2 = bucketRGEX2.test(bucketName);
      console.log('bucketName '+bucketName +' result '+result);
      console.log('bucketName '+bucketName +' result1 '+result1);
      console.log('bucketName '+bucketName +' result 2 '+result2);
      
      if(result && result1 && result2)
      {
        //condition pass
      }
      else
      {
          //not valid bucket name
      }  
      

      【讨论】:

        【解决方案7】:

        AWS 发布了新指南,其中“.”不推荐使用,现在禁止使用以“xn--”开头的存储桶名称 (https://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html)。如果您不允许使用 '.'正则表达式变得更具可读性:

        (?=^.{3,63}$)(?!xn--)([a-z0-9](?:[a-z0-9-]*)[a-z0-9])$

        【讨论】:

          【解决方案8】:

          编辑:修改正则表达式以允许所需的大小 (3-63) 并添加一些其他选项。

          名称必须符合 DNS 标准,因此您可以尝试:

          ^[A-Za-z0-9][A-Za-z0-9\-]{1,61}[A-Za-z0-9]$
          

          见:https://regexr.com/3psne

          如果您需要使用句点,请使用它:

          ^[A-Za-z0-9][A-Za-z0-9\-.]{1,61}[A-Za-z0-9]$
          

          见:https://regexr.com/3psnb

          最后,如果你想禁止两个连续的“非单词”字符,你可以使用:

          ^[A-Za-z0-9](?!.*[.-]{2})[A-Za-z0-9\-.]{1,61}[A-Za-z0-9]$
          

          见:https://regexr.com/3psn8

          基于:Regexp for subdomain

          【讨论】:

          • 这与 AWS 文档相差甚远。例如,这甚至不允许使用句点分隔符。
          • 我们还需要 3 到 64 个字符之间的长度限制。如何也能做到这一点
          • @TimBiegeleisen 如果我们现在可以忽略句点分隔符,我们可以为其他规则提供一个基本的正则表达式
          • @FellowBeginner 我修改了正则表达式以允许大小为 3-63。如果您还需要句号,您可以使用: "^[A-Za-z0-9][A-Za-z0-9\-.]{1,61}[A-Za-z0-9]$" 但是,这将允许'foo..bar'之类的东西。我不知道这是否应该允许。
          • @FellowBeginner 我还添加了一些其他选项
          【解决方案9】:

          我尝试将错误的存储桶名称传递给 S3 API 本身以查看它是如何验证的。看起来以下是 API 响应中返回的有效正则表达式模式。

          存储桶名称必须与正则表达式匹配

          ^[a-zA-Z0-9.\-_]{1,255}$
          

          或者是匹配正则表达式的 ARN

          ^arn:(aws).*:(s3|s3-object-lambda):[a-z\-0-9]+:[0-9]{12}:accesspoint[/:][a-zA-Z0-9\-]{1,63}$|^arn:(aws).*:s3-outposts:[a-z\-0-9]+:[0-9]{12}:outpost[/:][a-zA-Z0-9\-]{1,63}[/:]accesspoint[/:][a-zA-Z0-9\-]{1,63}$
          

          【讨论】:

            猜你喜欢
            • 2021-02-09
            • 2011-12-19
            • 2023-03-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-05-31
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多