如何从部署的上下文路径中排除路径?
How to exclude a path from the context path of a deployment?
我使用 Jetty 11。我在 /opt/web/mybase/webapps
中有两个上下文文件,一个用于 Certbot (Let's Encrypt),另一个用于根目录下的 Web 应用程序上下文。 The first context file must not redirect from HTTP to HTTPS in order to let Certbot work when the SSL certificate has just been revoked, its context path is /.well-known/acme-challenge
. The second context file must redirect from HTTP to HTTPS (by forcing the transport type "confidential" in web.xml), the context path is /
, it's similar to this context file. Certbot writes something in /.well-known/acme-challenge
and expects to see it at http://example.org/.well-known/acme-challenge.
如何在第二个上下文文件中指示除 /.well-known/acme-challenge
中的内容之外的所有内容都必须由此上下文文件中的 WAR 的 servlet 处理?
您需要信任 servlet 规范请求路径映射规则,事情会变得非常简单。
对于上下文路径,使用最长的匹配。
所以对于上下文 /foo
和 /
,以及 /foo/example.txt
的请求,最长的匹配是上下文 /foo
让我们看一下这个例子${jetty.base}
certbot-example/
├── etc/
│ └── keystore.p12
├── start.d/
│ ├── deploy.ini
│ ├── http.ini
│ ├── https.ini
│ ├── server.ini
│ └── ssl.ini
└── webapps/
├── ROOT/
│ ├── index.html
│ └── WEB-INF/
│ └── web.xml
├── well-known/
│ └── certbot.txt
└── well-known.xml
它具有以下配置...
$ java -jar ${JETTY_HOME}/start.jar --list-config
Enabled Modules:
----------------
0) resources transitive provider of resources for logging-jetty
1) logging/slf4j transitive provider of logging/slf4j for logging-jetty
dynamic dependency of logging-jetty
2) logging-jetty transitive provider of logging for threadpool
transitive provider of logging for bytebufferpool
transitive provider of logging for server
3) bytebufferpool transitive provider of bytebufferpool for server
init template available with --add-module=bytebufferpool
4) threadpool transitive provider of threadpool for server
init template available with --add-module=threadpool
5) server ${jetty.base}/start.d/server.ini
6) security transitive provider of security for webapp
7) servlet transitive provider of servlet for webapp
8) webapp transitive provider of webapp for deploy
init template available with --add-module=webapp
9) deploy ${jetty.base}/start.d/deploy.ini
10) http ${jetty.base}/start.d/http.ini
11) ssl ${jetty.base}/start.d/ssl.ini
12) https ${jetty.base}/start.d/https.ini
...(snip)...
Jetty Environment:
-----------------
jetty.version = 10.0.6
jetty.tag.version = jetty-10.0.6
jetty.build = 37e7731b4b142a882d73974ff3bec78d621bd674
jetty.home = /home/joakim/code/jetty/distros/jetty-home-10.0.6
jetty.base = /home/joakim/code/jetty/distros/bases/certbot-example
...(snip)...
Properties:
-----------
...(snip)...
jetty.httpConfig.securePort = 8443
在${jetty.base}/webapps/
中包含以下内容...
[certbot-example]$ cat webapps/ROOT/WEB-INF/web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>Example WebApp</display-name>
<security-constraint>
<web-resource-collection>
<web-resource-name>securedapp</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
</web-app>
[certbot-example]$ cat webapps/ROOT/index.html
<html><body><h2>Hello World!</h2></body></html>
[certbot-example]$ cat webapps/well-known/certbot.txt
example-cert-bot
[certbot-example]$ cat webapps/well-known.xml
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/.well-known</Set>
<Set name="war"><Property name="jetty.webapps" default="." />/well-known</Set>
</Configure>
启动码头后,我们可以看到部署了 2 个 webapps 上下文...
[certbot-example]$ java -jar ../../jetty-home-10.0.6/start.jar
2021-08-06 08:29:27.121:INFO :oejs.Server:main: jetty-10.0.6; built: 2021-06-29T15:28:56.259Z; git: 37e7731b4b142a882d73974ff3bec78d621bd674; jvm 11.0.12+7
2021-08-06 08:29:27.151:INFO :oejdp.ScanningAppProvider:main: Deployment monitor [file:///home/joakim/code/jetty/distros/bases/certbot-example/webapps/]
2021-08-06 08:29:27.227:INFO :oejw.StandardDescriptorProcessor:main: NO JSP Support for /.well-known, did not find org.eclipse.jetty.jsp.JettyJspServlet
2021-08-06 08:29:27.234:INFO :oejss.DefaultSessionIdManager:main: Session workerName=node0
2021-08-06 08:29:27.253:INFO :oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@30bce90b{/.well-known,file:///home/joakim/code/jetty/distros/bases/certbot-example/webapps/well-known/,AVAILABLE}{/home/joakim/code/jetty/distros/bases/certbot-example/webapps/well-known}
2021-08-06 08:29:27.264:INFO :oejw.StandardDescriptorProcessor:main: NO JSP Support for /, did not find org.eclipse.jetty.jsp.JettyJspServlet
2021-08-06 08:29:27.269:INFO :oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@10cf09e8{Example WebApp,/,file:///home/joakim/code/jetty/distros/bases/certbot-example/webapps/ROOT/,AVAILABLE}{/home/joakim/code/jetty/distros/bases/certbot-example/webapps/ROOT}
2021-08-06 08:29:27.432:INFO :oejus.SslContextFactory:main: x509=X509@57abad67(mykey,h=[localhost],a=[],w=[]) for Server@584f54e6[provider=null,keyStore=file:///home/joakim/code/jetty/distros/bases/certbot-example/etc/keystore.p12,trustStore=null]
2021-08-06 08:29:27.515:INFO :oejs.AbstractConnector:main: Started ServerConnector@1af687fe{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2021-08-06 08:29:27.522:INFO :oejs.AbstractConnector:main: Started ServerConnector@70efb718{SSL, (ssl, http/1.1)}{0.0.0.0:8443}
2021-08-06 08:29:27.534:INFO :oejs.Server:main: Started Server@1e16c0aa{STARTING}[10.0.6,sto=5000] @1071ms
注释的两个条目...
- 已开始 o.e.j.w.WebAppContext@30bce90b{
/.well-known
, file:///.../certbot-example/webapps/well-known/
, 可用}
- 已开始 o.e.j.w.WebAppContext@10cf09e8{Web 应用示例,
/
,file:///.../certbot-example/webapps/ROOT/
,可用}
这意味着我们定义了 2 个上下文,
一个用于向路径 http://<machine>/.well-known/
提供服务请求
另一个 http://<machine>/
如果我们发出一些请求,您会看到行为...
向上下文发出请求/.well-known
(注意 http 和 https 有效)
$ curl -vvv http://localhost:8080/.well-known/certbot.txt
* Trying 127.0.0.1:8080...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /.well-known/certbot.txt HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Last-Modified: Fri, 06 Aug 2021 13:11:32 GMT
< Content-Type: text/plain
< Accept-Ranges: bytes
< Content-Length: 17
< Server: Jetty(10.0.6)
<
example-cert-bot
$ curl -k -vvv https://localhost:8443/.well-known/certbot.txt
* Trying 127.0.0.1:8443...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
...(snip)...
* SSL certificate verify result: self signed certificate (18), continuing anyway.
> GET /.well-known/certbot.txt HTTP/1.1
> Host: localhost:8443
> User-Agent: curl/7.68.0
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Last-Modified: Fri, 06 Aug 2021 13:11:32 GMT
< Content-Type: text/plain
< Accept-Ranges: bytes
< Content-Length: 17
< Server: Jetty(10.0.6)
<
example-cert-bot
但是,如果我们从上下文中请求某些内容 /
,我们只能使用 https。
$ curl -k -L -vvv http://localhost:8080/
* Trying 127.0.0.1:8080...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 303 See Other
< Location: https://localhost:8443/
< Content-Length: 0
< Server: Jetty(10.0.6)
<
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'https://localhost:8443/'
* Trying 127.0.0.1:8443...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8443 (#1)
* ALPN, offering h2
* ALPN, offering http/1.1
..(snip)...
* SSL certificate verify result: self signed certificate (18), continuing anyway.
> GET / HTTP/1.1
> Host: localhost:8443
> User-Agent: curl/7.68.0
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Last-Modified: Fri, 06 Aug 2021 13:08:50 GMT
< Content-Type: text/html
< Accept-Ranges: bytes
< Content-Length: 48
< Server: Jetty(10.0.6)
<
<html><body><h2>Hello World!</h2></body></html>
* Connection #1 to host localhost left intact
我使用 Jetty 11。我在 /opt/web/mybase/webapps
中有两个上下文文件,一个用于 Certbot (Let's Encrypt),另一个用于根目录下的 Web 应用程序上下文。 The first context file must not redirect from HTTP to HTTPS in order to let Certbot work when the SSL certificate has just been revoked, its context path is /.well-known/acme-challenge
. The second context file must redirect from HTTP to HTTPS (by forcing the transport type "confidential" in web.xml), the context path is /
, it's similar to this context file. Certbot writes something in /.well-known/acme-challenge
and expects to see it at http://example.org/.well-known/acme-challenge.
如何在第二个上下文文件中指示除 /.well-known/acme-challenge
中的内容之外的所有内容都必须由此上下文文件中的 WAR 的 servlet 处理?
您需要信任 servlet 规范请求路径映射规则,事情会变得非常简单。
对于上下文路径,使用最长的匹配。
所以对于上下文 /foo
和 /
,以及 /foo/example.txt
的请求,最长的匹配是上下文 /foo
让我们看一下这个例子${jetty.base}
certbot-example/
├── etc/
│ └── keystore.p12
├── start.d/
│ ├── deploy.ini
│ ├── http.ini
│ ├── https.ini
│ ├── server.ini
│ └── ssl.ini
└── webapps/
├── ROOT/
│ ├── index.html
│ └── WEB-INF/
│ └── web.xml
├── well-known/
│ └── certbot.txt
└── well-known.xml
它具有以下配置...
$ java -jar ${JETTY_HOME}/start.jar --list-config
Enabled Modules:
----------------
0) resources transitive provider of resources for logging-jetty
1) logging/slf4j transitive provider of logging/slf4j for logging-jetty
dynamic dependency of logging-jetty
2) logging-jetty transitive provider of logging for threadpool
transitive provider of logging for bytebufferpool
transitive provider of logging for server
3) bytebufferpool transitive provider of bytebufferpool for server
init template available with --add-module=bytebufferpool
4) threadpool transitive provider of threadpool for server
init template available with --add-module=threadpool
5) server ${jetty.base}/start.d/server.ini
6) security transitive provider of security for webapp
7) servlet transitive provider of servlet for webapp
8) webapp transitive provider of webapp for deploy
init template available with --add-module=webapp
9) deploy ${jetty.base}/start.d/deploy.ini
10) http ${jetty.base}/start.d/http.ini
11) ssl ${jetty.base}/start.d/ssl.ini
12) https ${jetty.base}/start.d/https.ini
...(snip)...
Jetty Environment:
-----------------
jetty.version = 10.0.6
jetty.tag.version = jetty-10.0.6
jetty.build = 37e7731b4b142a882d73974ff3bec78d621bd674
jetty.home = /home/joakim/code/jetty/distros/jetty-home-10.0.6
jetty.base = /home/joakim/code/jetty/distros/bases/certbot-example
...(snip)...
Properties:
-----------
...(snip)...
jetty.httpConfig.securePort = 8443
在${jetty.base}/webapps/
中包含以下内容...
[certbot-example]$ cat webapps/ROOT/WEB-INF/web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>Example WebApp</display-name>
<security-constraint>
<web-resource-collection>
<web-resource-name>securedapp</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
</web-app>
[certbot-example]$ cat webapps/ROOT/index.html
<html><body><h2>Hello World!</h2></body></html>
[certbot-example]$ cat webapps/well-known/certbot.txt
example-cert-bot
[certbot-example]$ cat webapps/well-known.xml
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/.well-known</Set>
<Set name="war"><Property name="jetty.webapps" default="." />/well-known</Set>
</Configure>
启动码头后,我们可以看到部署了 2 个 webapps 上下文...
[certbot-example]$ java -jar ../../jetty-home-10.0.6/start.jar
2021-08-06 08:29:27.121:INFO :oejs.Server:main: jetty-10.0.6; built: 2021-06-29T15:28:56.259Z; git: 37e7731b4b142a882d73974ff3bec78d621bd674; jvm 11.0.12+7
2021-08-06 08:29:27.151:INFO :oejdp.ScanningAppProvider:main: Deployment monitor [file:///home/joakim/code/jetty/distros/bases/certbot-example/webapps/]
2021-08-06 08:29:27.227:INFO :oejw.StandardDescriptorProcessor:main: NO JSP Support for /.well-known, did not find org.eclipse.jetty.jsp.JettyJspServlet
2021-08-06 08:29:27.234:INFO :oejss.DefaultSessionIdManager:main: Session workerName=node0
2021-08-06 08:29:27.253:INFO :oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@30bce90b{/.well-known,file:///home/joakim/code/jetty/distros/bases/certbot-example/webapps/well-known/,AVAILABLE}{/home/joakim/code/jetty/distros/bases/certbot-example/webapps/well-known}
2021-08-06 08:29:27.264:INFO :oejw.StandardDescriptorProcessor:main: NO JSP Support for /, did not find org.eclipse.jetty.jsp.JettyJspServlet
2021-08-06 08:29:27.269:INFO :oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@10cf09e8{Example WebApp,/,file:///home/joakim/code/jetty/distros/bases/certbot-example/webapps/ROOT/,AVAILABLE}{/home/joakim/code/jetty/distros/bases/certbot-example/webapps/ROOT}
2021-08-06 08:29:27.432:INFO :oejus.SslContextFactory:main: x509=X509@57abad67(mykey,h=[localhost],a=[],w=[]) for Server@584f54e6[provider=null,keyStore=file:///home/joakim/code/jetty/distros/bases/certbot-example/etc/keystore.p12,trustStore=null]
2021-08-06 08:29:27.515:INFO :oejs.AbstractConnector:main: Started ServerConnector@1af687fe{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2021-08-06 08:29:27.522:INFO :oejs.AbstractConnector:main: Started ServerConnector@70efb718{SSL, (ssl, http/1.1)}{0.0.0.0:8443}
2021-08-06 08:29:27.534:INFO :oejs.Server:main: Started Server@1e16c0aa{STARTING}[10.0.6,sto=5000] @1071ms
注释的两个条目...
- 已开始 o.e.j.w.WebAppContext@30bce90b{
/.well-known
,file:///.../certbot-example/webapps/well-known/
, 可用} - 已开始 o.e.j.w.WebAppContext@10cf09e8{Web 应用示例,
/
,file:///.../certbot-example/webapps/ROOT/
,可用}
这意味着我们定义了 2 个上下文,
一个用于向路径 http://<machine>/.well-known/
提供服务请求
另一个 http://<machine>/
如果我们发出一些请求,您会看到行为...
向上下文发出请求/.well-known
(注意 http 和 https 有效)
$ curl -vvv http://localhost:8080/.well-known/certbot.txt
* Trying 127.0.0.1:8080...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /.well-known/certbot.txt HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Last-Modified: Fri, 06 Aug 2021 13:11:32 GMT
< Content-Type: text/plain
< Accept-Ranges: bytes
< Content-Length: 17
< Server: Jetty(10.0.6)
<
example-cert-bot
$ curl -k -vvv https://localhost:8443/.well-known/certbot.txt
* Trying 127.0.0.1:8443...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
...(snip)...
* SSL certificate verify result: self signed certificate (18), continuing anyway.
> GET /.well-known/certbot.txt HTTP/1.1
> Host: localhost:8443
> User-Agent: curl/7.68.0
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Last-Modified: Fri, 06 Aug 2021 13:11:32 GMT
< Content-Type: text/plain
< Accept-Ranges: bytes
< Content-Length: 17
< Server: Jetty(10.0.6)
<
example-cert-bot
但是,如果我们从上下文中请求某些内容 /
,我们只能使用 https。
$ curl -k -L -vvv http://localhost:8080/
* Trying 127.0.0.1:8080...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 303 See Other
< Location: https://localhost:8443/
< Content-Length: 0
< Server: Jetty(10.0.6)
<
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'https://localhost:8443/'
* Trying 127.0.0.1:8443...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8443 (#1)
* ALPN, offering h2
* ALPN, offering http/1.1
..(snip)...
* SSL certificate verify result: self signed certificate (18), continuing anyway.
> GET / HTTP/1.1
> Host: localhost:8443
> User-Agent: curl/7.68.0
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Last-Modified: Fri, 06 Aug 2021 13:08:50 GMT
< Content-Type: text/html
< Accept-Ranges: bytes
< Content-Length: 48
< Server: Jetty(10.0.6)
<
<html><body><h2>Hello World!</h2></body></html>
* Connection #1 to host localhost left intact