Testing FME WebSocket with OpenSSL and WSCAT
Categories:
Projects: c2platform/rws/ansible-gis
, c2platform.wincore
,
c2platform.gis
When FME Flow is installed, WebSockets are configured by default using the ws
protocol. In the Ansible inventory project c2platform/rws/ansible-gis
, WebSockets are
configured to be secure and use the wss
protocol. Misconfiguration can break
the WebSockets feature. This guide offers three methods to verify WebSocket
functionality:
- Using the OpenSSL Library.
- Using the WSCAT utility.
- Using a custom PowerShell script.
Prerequisites
- Follow Setting Up FME Flow with Ansible to set up the FME environment,
which consists of
gsd-fme-core
,gsd-ad
,gsd-db1
, andgsd-rproxy1
. These nodes should be up and running.
SSH into gsd-rproxy1
To run the tests using OpenSSL and WSCAT, connect to gsd-rproxy1
:
vagrant ssh gsd-rproxy1
Test WebSocket using OpenSSL
The gsd-rproxy1
node has the OpenSSL library installed by default.
Establish a secure SSL/TLS connection to the server:
openssl s_client -connect gsd-fme-core:7078
Show me
root@gsd-rproxy1:~# openssl s_client -connect gsd-fme-core:7078 CONNECTED(00000003) Can't use SSL_get_servername depth=1 CN = c2 verify return:1 depth=0 C = NL, ST = Zuid-Holland, L = Den Haag, O = C2, OU = C2 GIS Platform Team, CN = gsd-fme-core verify return:1 --- Certificate chain 0 s:C = NL, ST = Zuid-Holland, L = Den Haag, O = C2, OU = C2 GIS Platform Team, CN = gsd-fme-core i:CN = c2 a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA256 v:NotBefore: Sep 2 07:34:13 2024 GMT; NotAfter: Aug 31 07:34:13 2034 GMT --- Server certificate -----BEGIN CERTIFICATE----- MIIFyjCCA7KgAwIBAgIUFMVOmvJuY7/68kemIj6HCLuiTy4wDQYJKoZIhvcNAQEL BQAwDTELMAkGA1UEAwwCYzIwHhcNMjQwOTAyMDczNDEzWhcNMzQwODMxMDczNDEz WjB6MQswCQYDVQQGEwJOTDEVMBMGA1UECAwMWnVpZC1Ib2xsYW5kMREwDwYDVQQH (lines deleted) bocbN6ZKuDSO4087FzwjMOJ5yGxMAQymcGmiyZrM4D5iIrf3ozr8SAQ3lXDAnfZ9 0RG2T5QteaD9ThQOsseGBq6HURphzOFtzL/FGR1nNr6jCGA5001+FQ/77dP84A== -----END CERTIFICATE----- subject=C = NL, ST = Zuid-Holland, L = Den Haag, O = C2, OU = C2 GIS Platform Team, CN = gsd-fme-core issuer=CN = c2 --- No client certificate CA names sent Peer signing digest: SHA256 Peer signature type: RSA-PSS Server Temp Key: X25519, 253 bits --- SSL handshake has read 2274 bytes and written 373 bytes Verification: OK --- New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384 Server public key is 4096 bit Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated Early data was not sent Verify return code: 0 (ok) --- --- Post-Handshake New Session Ticket arrived: SSL-Session: Protocol : TLSv1.3 Cipher : TLS_AES_256_GCM_SHA384 Session-ID: 8AC31E962569F35F4A9C6FD9DE5FF5308D819A012DB754FFF88ED573E19C5DF1 Session-ID-ctx: Resumption PSK: 727A2C1C5D2B4EC513E941C9C759998493743FADED7E74E92AADC4C951EDF6A43E59775010FB465920C07B57DE42F96A PSK identity: None PSK identity hint: None SRP username: None TLS session ticket lifetime hint: 86400 (seconds) TLS session ticket: 0000 - 7a b5 a3 f2 b0 91 51 91-6a 90 1c 40 3f 8f 79 f4 z.....Q.j..@?.y. 0010 - fe 9f 42 86 fe 69 b1 20-45 2c 04 ff 0a 6f cd 6a ..B..i. E,...o.j 0020 - 29 8c 99 c2 d8 79 aa 17-11 53 56 ab c8 2a fc 22 )....y...SV..*." (lines deleted) 06a0 - 43 d6 b3 c1 7f 62 55 50-7d a3 53 a4 3d 2c c3 30 C....bUP}.S.=,.0 06b0 - 56 5d a9 ef 21 e0 8e 1e-27 0c f9 cf 61 ed V]..!...'...a. Start Time: 1725356133 Timeout : 7200 (sec) Verify return code: 0 (ok) Extended master secret: no Max Early Data: 0
Initiate the WebSocket handshake by manually inputting the following lines after the secure connection is established:
GET /websocket HTTP/1.1 Host: gsd-fme-core:7078 Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: h3aOngl22xTlrMuoCGC4+w== Sec-WebSocket-Version: 13
Note:
Sec-WebSocket-Key
is a Base64-encoded random value1.To submit your input, press enter twice to send a double newline.
The response should be something like:
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: AEwKHncza7ZXcfBb5yM/aluzmpE=
This response indicates a successful WebSocket handshake, confirming that the HTTP connection is now upgraded to a WebSocket connection.
To perform a more comprehensive test that also validates the wss
scheme, you
will need a WebSocket client library like WSCAT2.
WSCAT
This section describes how to validate FME WebSockets using WSCAT .
Install NodeJS, NPM, and WSCAT
To install WSCAT, run the following commands on the gsd-proxy1
node:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
nvm install 20
node -v
npm -v
npm install -g wscat
Show me
vagrant@gsd-rproxy1:~$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
nvm install 20
node -v
npm -v
npm install -g wscat
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 15916 100 15916 0 0 68354 0 --:--:-- --:--:-- --:--:-- 68603
=> Downloading nvm from git to '/home/vagrant/.nvm'
=> Cloning into '/home/vagrant/.nvm'...
remote: Enumerating objects: 376, done.
remote: Counting objects: 100% (376/376), done.
remote: Compressing objects: 100% (324/324), done.
remote: Total 376 (delta 43), reused 168 (delta 25), pack-reused 0 (from 0)
Receiving objects: 100% (376/376), 374.67 KiB | 6.46 MiB/s, done.
Resolving deltas: 100% (43/43), done.
* (HEAD detached at FETCH_HEAD)
master
=> Compressing and cleaning up git repository
=> Appending nvm source string to /home/vagrant/.bashrc
=> Appending bash_completion source string to /home/vagrant/.bashrc
=> Close and reopen your terminal to start using nvm or run the following to use it now:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
Downloading and installing node v20.17.0...
Downloading https://nodejs.org/dist/v20.17.0/node-v20.17.0-linux-x64.tar.xz...
#################################################################################################### 100.0%
Computing checksum with sha256sum
Checksums matched!
Now using node v20.17.0 (npm v10.8.2)
Creating default alias: default -> 20 (-> v20.17.0)
v20.17.0
10.8.2
added 9 packages in 1s
npm notice
npm notice New patch version of npm available! 10.8.2 -> 10.8.3
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.8.3
npm notice To update run: npm install -g npm@10.8.3
npm notice
vagrant@gsd-rproxy1:~$ wscat --help
Usage: wscat [options] (--listen <port> | --connect <url>)
Options:
-V, --version output the version number
--auth <username:password> add basic HTTP authentication header (--connect only)
--ca <ca> specify a Certificate Authority (--connect only)
--cert <cert> specify a Client SSL Certificate (--connect only)
--host <host> optional host
--key <key> specify a Client SSL Certificate's key (--connect only)
--max-redirects [num] maximum number of redirects allowed (--connect only) (default: 10)
--no-color run without color
--passphrase [passphrase] specify a Client SSL Certificate Key's passphrase (--connect only).
If you don't provide a value, it will be prompted for
--proxy <[protocol://]host[:port]> connect via a proxy. Proxy must support CONNECT method
--slash enable slash commands for control frames (/ping [data], /pong
[data], /close [code [, reason]])
-c, --connect <url> connect to a WebSocket server
-H, --header <header:value> set an HTTP header. Repeat to set multiple (--connect only)
(default: [])
-L, --location follow redirects (--connect only)
-l, --listen <port> listen on port
-n, --no-check do not check for unauthorized certificates
-o, --origin <origin> optional origin
-p, --protocol <version> optional protocol version
-P, --show-ping-pong print a notification when a ping or pong is received
-s, --subprotocol <protocol> optional subprotocol (default: [])
-w, --wait <seconds> wait given seconds after executing command
-x, --execute <command> execute command after connecting
-h, --help display help for command
vagrant@gsd-rproxy1:~$
Test WebSocket using WSCAT
To test the WebSocket using WSCAT, run the following command on gsd-rproxy1
:
wscat -c wss://gsd-fme-core:7078/websocket --ca /vagrant/.ca/c2/c2.crt
This command should respond with “Connected (press CTRL+C to quit)”. Note that
you have to provide the Certificate Authority (CA) bundle/certificate c2.crt
.
Alternatively, you can provide -n
or --no-check
to skip certificate
verification. See wscat --help
for more options.
Show me
vagrant@gsd-rproxy1:~$ wscat -c wss://gsd-fme-core:7078/websocket --ca /vagrant/.ca/c2/c2.crt
Connected (press CTRL+C to quit)
> vagrant@gsd-rproxy1:~$ wscat -c wss://gsd-fme-core:7078/websocket -n
Connected (press CTRL+C to quit)
> vagrant@gsd-rproxy1:~$ wscat -c wss://gsd-fme-core:7078/websocket
error: unable to verify the first certificate
> vagrant@gsd-rproxy1:~$
Test WebSocket using PowerShell
You can also use a simple PowerShell script to test the connection. First,
connect to the FME Flow node gsd-fme-core
:
vagrant ssh gds-fme-core
Start PowerShell:
powershell
Execute the script websocket-test.ps1
:
cd c:\vagrant\scripts\gsd-fme-core
.\websocket-test.ps1
Show me
Microsoft Windows [Version 10.0.20348.707]
(c) Microsoft Corporation. All rights reserved.
vagrant@GSD-FME-CORE C:\Users\vagrant>cd c:\vagrant\scripts\gsd-fme-core
vagrant@GSD-FME-CORE c:\vagrant\scripts\gsd-fme-core>powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows
PS C:\vagrant\scripts\gsd-fme-core> .\websocket-test.ps1
Successfully established secure WebSocket connection
PS C:\vagrant\scripts\gsd-fme-core>
Footnotes
The key
Sec-WebSocket-Key
is a Base64-encoded random value generated by the client. This value is used by the server to generate a response key for agreeing to the WebSocket connection. You can generate your ownSec-WebSocket-Key
using the command:↩︎openssl rand -base64 16
The test using the OpenSSL library command opens a TLS/SSL connection to the specified server. This ensures that the underlying transport (from client to server) is encrypted using TLS/SSL. However, the WebSocket protocol negotiated over that connection is separate from the security offered by the transport layer. To test
wss
specifically, use a WebSocket client library (like WSCAT or a browser with WebSocket support), specifying thewss
scheme. ↩︎
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.