What's?
WildFlyでAJPが使えるように設定してみよう、ということで。
WildFlyにAJPを設定して、Apacheのmod_proxy_ajpで連携するところまでやってみたいと思います。
環境
今回の環境はこちら。CentOS 8です。
$ cat /etc/redhat-release
CentOS Linux release 8.4.2105
$ uname -srvmpio
Linux 4.18.0-305.12.1.el8_4.x86_64 #1 SMP Wed Aug 11 01:59:55 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Javaはこちら。
$ java --version
openjdk 11.0.12 2021-07-20 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.12+7-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.12+7-LTS, mixed mode, sharing)
WildFlyでAJPを設定するための情報
設定方法は、ドキュメントを見るのが筋でしょうということで。
こちらを見ればよさそうです。
手順的には、以下のようです。
- AJP用の
socket-binding
の定義 -
ajp-listener
を追加
こちらに沿ってやっていきましょう。
サンプルアプリケーション
動作確認をするためのアプリケーションが必要ですね、サンプルを作りましょう。
Mavenプロジェクトで、JAX-RSを使ったアプリケーションにします。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>simple-jaxrs</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
<dependencies>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-web-api</artifactId>
<version>8.0.0</version>
</dependency>
</dependencies>
<build>
<finalName>ROOT</finalName>
</build>
</project>
JAX-RSリソースクラス。
package com.example;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
@Path("message")
public class MessageResource {
@GET
@Path("hello-world")
@Produces(MediaType.TEXT_PLAIN)
public String helloWorld() {
return "Hello World!!";
}
@GET
@Path("build")
@Produces(MediaType.TEXT_PLAIN)
public String build(@QueryParam("word") String word) {
return String.format("Hello %s!!", word);
}
}
JAX-RSの有効化。
package com.example;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("")
public class JaxrsApp extends Application {
}
パッケージング。
$ mvn package
ROOT.war
というファイルができあがるので、こちらを使います。
WildFlyのインストール
まずはWildFlyをインストールをします。24.0.1を使います。
$ curl -LO https://download.jboss.org/wildfly/24.0.1.Final/wildfly-24.0.1.Final.zip
$ unzip wildfly-24.0.1.Final.zip
$ cd wildfly-24.0.1.Final
スタンドアロンサーバーとして起動。
$ bin/standalone.sh
管理CLIに接続。
$ bin/jboss-cli.sh -c
アプリケーションをデプロイ。
[standalone@localhost:9990 /] deploy /path/to/target/ROOT.war
まずは動作確認。
$ curl localhost:8080/message/hello-world
Hello World!!
$ curl localhost:8080/message/build?word=WildFly
Hello WildFly!!
ここまでで、AJPを設定する前までの準備は完了です。
WildFlyにAJPリスナーを設定する
最初にsocket-binding
の設定を見てみます。
デフォルトで、AJP用のsocket-binding
の定義が入っているようです。
[standalone@localhost:9990 /] /socket-binding-group=standard-sockets/socket-binding=ajp:read-resource(include-runtime)
{
"outcome" => "success",
"result" => {
"bound" => false,
"bound-address" => undefined,
"bound-port" => undefined,
"client-mappings" => undefined,
"fixed-port" => false,
"interface" => undefined,
"multicast-address" => undefined,
"multicast-port" => undefined,
"name" => "ajp",
"port" => expression "${jboss.ajp.port:8009}"
}
}
8009
ポートを使うようですが、リッスンはしていないようです。
$ sudo ss -tnlp | grep java
LISTEN 0 128 127.0.0.1:8080 0.0.0.0:* users:(("java",pid=1409,fd=489))
LISTEN 0 128 127.0.0.1:8443 0.0.0.0:* users:(("java",pid=1409,fd=379))
LISTEN 0 50 127.0.0.1:9990 0.0.0.0:* users:(("java",pid=1409,fd=510))
実際にAJPでリッスンさせるためには、Undertowサブシステムにajp-listenerを追加する必要があります。
[standalone@localhost:9990 /] /subsystem=undertow/server=default-server/ajp-listener=ajp:add(socket-binding=ajp)
{"outcome" => "success"}
これで、AJPでリッスンするようになりました。
$ sudo ss -tnlp | grep java
LISTEN 0 128 127.0.0.1:8080 0.0.0.0:* users:(("java",pid=1409,fd=489))
LISTEN 0 128 127.0.0.1:8443 0.0.0.0:* users:(("java",pid=1409,fd=379))
LISTEN 0 50 127.0.0.1:9990 0.0.0.0:* users:(("java",pid=1409,fd=510))
LISTEN 0 128 127.0.0.1:8009 0.0.0.0:* users:(("java",pid=1409,fd=554))
Apache+mod_proxy_ajpを設定する
次は、ApacheからWildFlyにプロキシするように設定してみましょう。
Apacheをインストール。
$ sudo dnf install httpd
バージョンはこちら。
$ httpd -V
Server version: Apache/2.4.37 (centos)
Server built: May 20 2021 04:33:06
Server's Module Magic Number: 20120211:83
Server loaded: APR 1.6.3, APR-UTIL 1.6.1
Compiled using: APR 1.6.3, APR-UTIL 1.6.1
Architecture: 64-bit
Server MPM: event
threaded: yes (fixed thread count)
forked: yes (variable process count)
Server compiled with....
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
-D APR_USE_SYSVSEM_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D DYNAMIC_MODULE_LIMIT=256
-D HTTPD_ROOT="/etc/httpd"
-D SUEXEC_BIN="/usr/sbin/suexec"
-D DEFAULT_PIDLOG="run/httpd.pid"
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
-D DEFAULT_ERRORLOG="logs/error_log"
-D AP_TYPES_CONFIG_FILE="conf/mime.types"
-D SERVER_CONFIG_FILE="conf/httpd.conf"
httpd.conf
に以下の設定を追加。
ProxyPass / ajp://localhost:8009/
ProxyPassReverse / http://localhost:8009/
で、アクセスすると503
になり、こんなエラーがApacheのエラーログに記録されます。
[Sun Aug 15 21:22:03.317824 2021] [proxy:error] [pid 2508:tid 139935789078272] (13)Permission denied: AH00957: AJP: attempt to connect to 127.0.0.1:8009 (localhost) failed
/var/log/audit/audit.log
を見ると、こんな感じに。
type=AVC msg=audit(1629030335.451:283): avc: denied { name_connect } for pid=2510 comm="httpd" dest=8009 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:http_port_t:s0 tclass=tcp_socket permissive=0
type=SYSCALL msg=audit(1629030335.451:283): arch=c000003e syscall=42 success=no exit=-13 a0=10 a1=55e68b55ddb0 a2=10 a3=7f45637fd82c items=0 ppid=2506 pid=2510 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null)ARCH=x86_64 SYSCALL=connect AUID="unset" UID="apache" GID="apache" EUID="apache" SUID="apache" FSUID="apache" EGID="apache" SGID="apache" FSGID="apache"
type=PROCTITLE msg=audit(1629030335.451:283): proctitle=2F7573722F7362696E2F6874747064002D44464F524547524F554E44
type=AVC msg=audit(1629030335.451:284): avc: denied { name_connect } for pid=2510 comm="httpd" dest=8009 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:http_port_t:s0 tclass=tcp_socket permissive=0
type=SYSCALL msg=audit(1629030335.451:284): arch=c000003e syscall=42 success=no exit=-13 a0=10 a1=55e68b55de80 a2=10 a3=7f45637fd82c items=0 ppid=2506 pid=2510 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null)ARCH=x86_64 SYSCALL=connect AUID="unset" UID="apache" GID="apache" EUID="apache" SUID="apache" FSUID="apache" EGID="apache" SGID="apache" FSGID="apache"
type=PROCTITLE msg=audit(1629030335.451:284): proctitle=2F7573722F7362696E2F6874747064002D44464F524547524F554E44
SELinuxに阻まれているようなので、以下のように設定します。
$ sudo setsebool -P httpd_can_network_connect 1
これで、Apache(mod_proxy_ajp) → WildFly(AJP)にアクセスできるようになりました。
$ curl localhost/message/hello-world
Hello World!!
$ curl localhost/message/build?word=WildFly
Hello WildFly!!
これで、やりたい構成はできました、と。
AJPの設定を自分でしてみる
デフォルトでsocket-binding
が入っていたので、これを自分で追加するところからやってみましょう。
まずは、ここまでに定義したajp-listener
を削除、socket-biding
も削除。
[standalone@localhost:9990 /] /subsystem=undertow/server=default-server/ajp-listener=ajp:remove()
{
"outcome" => "success",
"response-headers" => {
"operation-requires-reload" => true,
"process-state" => "reload-required"
}
}
[standalone@localhost:9990 /] /socket-binding-group=standard-sockets/socket-binding=ajp:remove()
{
"outcome" => "success",
"response-headers" => {
"operation-requires-reload" => true,
"process-state" => "reload-required"
}
}
追加は、こうですね。
[standalone@localhost:9990 /] /socket-binding-group=standard-sockets/socket-binding=ajp:add(port=8009,interface=public)
{"outcome" => "success"}
[standalone@localhost:9990 /] /subsystem=undertow/server=default-server/ajp-listener=ajp:add(socket-binding=ajp)
{"outcome" => "success"}