Okay, a bit of progress. I set the security policy to None and saw no immediate improvement. Busted out Wireshark and saw that XLReporter was trying to use the static IP address of the server for communications, not localhost or 127.0.0.1.
I added the IP address of the server to the Bind Addresses list, and after testing the connection got a new error in the gateway logs:
[remote=/192.168.1.10:51087] Exception caught; sent ErrorMessage{error=StatusCode{name=Bad_SecurityChecksFailed, value=0x80130000, quality=bad}, reason=certificate path validation failed}
Then, went under Configure > OPC UA > Security > Server and accepted the quarantined certificate that showed up for XLReporterOPC.UA. My server security page looks like this now
Now when I test the connection from XLReporter, I get this error:
UascServerAsymmetricHandler 07May2020 15:16:56 Error decoding asymmetric message: could not verify signature
org.eclipse.milo.opcua.stack.core.UaException: could not verify signature
at org.eclipse.milo.opcua.stack.core.channel.ChunkDecoder$AsymmetricDecoder.verifyChunk(ChunkDecoder.java:318)
at org.eclipse.milo.opcua.stack.core.channel.ChunkDecoder$AbstractDecoder.decode(ChunkDecoder.java:150)
at org.eclipse.milo.opcua.stack.core.channel.ChunkDecoder.decode(ChunkDecoder.java:84)
at org.eclipse.milo.opcua.stack.core.channel.ChunkDecoder.decodeAsymmetric(ChunkDecoder.java:64)
at org.eclipse.milo.opcua.stack.server.transport.uasc.UascServerAsymmetricHandler.lambda$onOpenSecureChannel$0(UascServerAsymmetricHandler.java:248)
at org.eclipse.milo.opcua.stack.core.channel.SerializationQueue.lambda$decode$1(SerializationQueue.java:61)
at org.eclipse.milo.opcua.stack.core.util.ExecutionQueue$Task.run(ExecutionQueue.java:119)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
