写这个 IP 阀的正确方法是什么?

What's the correct way to write this IP valve?

我正在尝试使用阀门通过请求者的 IP 地址来控制对我的 tomcat(版本 8)服务器的访问。我想要的是允许所有不以 10 开头的地址和所有以 10.10 开头的地址。这是我的。

<valve className="org.apache.catalina.valves.RemoteAddrValve"> allow="[^10]\.\d+\.\d+\.\d+|10\.10\.\d+\.\d+" />

它不起作用,它只允许访问以 10.10 开头的地址。

正则表达式不是我最好的东西,我做错了什么?

谢谢。

[^10] 不会排除以 10 开头的字符串,它会匹配任何非 1 或 0 的字符。因此,您的模式的第一部分将接受以下 IP 地址: 2.X.Y.Z, 3.X.Y.Z, ..., 9.X.Y.Z.

为了实现你的目标,你可以尝试这样的事情:

d\.\d+\.\d+\.\d+|[02-9]d\.\d+\.\d+\.\d+|[1-9]dd\.\d+\.\d+\.\d+|10\.10\.\d+\.\d+

这样,第一个备选方案将接受任何以单个数字开头的 IP。第二个,任何以两位数开头的 IP,不包括 10。第三个,任何以三位开头的 IP(因此也不能是 10)。

还有一点要注意:通过使用 d+ 来匹配数字,即使是无效值也可能被接受为 IP 组件(应该在 0-255 之间),例如 257、3848 等。但这可能没问题针对您的问题域。

允许所有以 10.10 开头的地址。您可以使用以下正则表达式:

10\.10\..*

\. 对应 "dot" 字符,.* 对应任何字符。

要禁止所有以 10. 开头的地址,您必须编写更复杂的内容:[^1].* 对应于任何不以 1 开头的内容。没关系,如果 IP 地址不以 1 开头,我们将允许它。 1[^0].*对应任何以1开头但第二个字符不是0的IP地址。 11xxx15xxx 等。但是我们必须允许像 101.xxx 这样的地址。所以我们将不得不写10[^.].*。此表达式将允许除 10.xxx 之外的任何内容,这很好。

所以最终的正则表达式看起来像是上面所有表达式之间的替代:

10\.10\..*|[^1].*|1[^0].*|10[^.].*

或者稍微简化一下:

(10\.10\.|[^1]|1[^0]|10[^.]).*

现在最好在开头添加 ^ 并在结尾添加 $,以确保此表达式将检查整个 IP 地址:

^(10\.10\.|[^1]|1[^0]|10[^.]).*$

我根本没有检查输入值是否为 IP 地址,但我确定 tomcat 不会通过此检查的 IP 地址以外的任何内容。