https://github.com/ammbra/tictactoe
Simple SSL enabled tictactoe game with SpringBoot, deployed with docker/podman compose. The game is used to observe JFR events in Prometheus.
https://github.com/ammbra/tictactoe
jdk23 jfr ssl tls
Last synced: 8 months ago
JSON representation
Simple SSL enabled tictactoe game with SpringBoot, deployed with docker/podman compose. The game is used to observe JFR events in Prometheus.
- Host: GitHub
- URL: https://github.com/ammbra/tictactoe
- Owner: ammbra
- License: upl-1.0
- Created: 2024-03-08T21:29:52.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-09-30T10:08:38.000Z (over 1 year ago)
- Last Synced: 2025-02-18T04:31:10.047Z (over 1 year ago)
- Topics: jdk23, jfr, ssl, tls
- Language: Java
- Homepage:
- Size: 49.8 KB
- Stars: 0
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# TicTacToe
A sample web app to play Tic Tac Toe against the computer. The application requires minimum JDK 21 to run locally.
## Technologies
This application has several components:
* Running on JDK 21+ and built with Maven.
* Setup built with Spring Boot (v3.2.2), persistency layer with JPA and H2 database, UI with Thymeleaf with Bootstrap
* Containerized with Dockerfile and deployed with Docker Compose.
| UI Component | Link |
|-----------------------------|----------------------------------------------------|
| Header | https://getbootstrap.com/docs/5.3/examples/headers/|
| Footer | https://getbootstrap.com/docs/5.3/examples/footers/|
| Sign In and Register | https://getbootstrap.com/docs/5.3/examples/sign-in/|
## How to create the keystore and truststore
In order to build an example keystore, you can use the following series of commands:
1. Create a CA certificate, by running `openssl req -x509 -sha256 -days 3650 -newkey rsa:4096 -keyout localCA.key -out localCA.crt`
2. Create a certificate signing request, by running `openssl req -new -newkey rsa:4096 -keyout localhost.key -out localhost.csr`
3. Make an extension file (`local.ext`) containing additional hosts and IPs that your certificate should authorize:
```txt{local.ext}
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = springboot
IP.1 = 127.0.0.1
```
4. Sign the request with our localCA.crt certificate and its private key:
```shell
openssl x509 -req -CA localCA.crt -CAkey localCA.key -in localhost.csr \
-out localhost.crt -days 365 -CAcreateserial -extfile local.ext
```
5. Create the keystore by importing the certificate created at previous step:
```shell
openssl pkcs12 -export -out keystore.p12 -name "localhost" -inkey localhost.key -in localhost.crt
```
To enable mutual authentication, you need to generate a truststore and generate client certificates:
1. Create a truststore by running:
```shell
keytool -import -trustcacerts -noprompt -alias ca -ext san=dns:localhost,ip:127.0.0.1 -file localCA.crt -keystore truststore.p12
```
2. Generate a client-side certificate signing request with common name (CN) Ana:
```shell
openssl req -new -newkey rsa:4096 -nodes -keyout ana.key -out ana.csr -subj '/CN=ana'
```
3. Sign the request with the existing CA:
```shell
openssl x509 -req -CA localCA.crt -CAkey localCA.key -in ana.csr -out ana.crt -days 365 -CAcreateserial
```
4. Package the signed certificate and the private key into the PKCS file:
```shell
openssl pkcs12 -export -out ana.p12 -name "ana" -inkey ana.key -in ana.crt
```
5. Import the generated certificate (`ana.p12`) in your browser.
Do not forget to reference the location of your keystore/truststore in the `application.properties` file:
```text
server.ssl.bundle=mybundle
spring.ssl.bundle.jks.mybundle.keystore.location=stores/keystore.p12
spring.ssl.bundle.jks.mybundle.truststore.location=stores/truststore.p12
```
**IMPORTANT** For demo purposes, `application.properties` contains the passwords in clear.
For production environments you must consider encrypting your passwords.
## How to play
You can start the application locally
from your IDE or by running the following command in a terminal window:
```
./mvnw spring-boot:run
```
When accessing the application on https://localhost:8443, you will be asked to sign in to play. If you didn't register,
you can do so by clicking [the register link](https://localhost:8443/register).
If there is an user already registered with a chosen username, please select a different one.
Once you register, login with your chosen username and password to play. Have fun!
## How to deploy
You can deploy the application locally via Docker Compose. First build the application using:
```
./mvnw clean verify
```
By default, the provided docker compose file has enabled remote JMX connection via `JDK_JAVA_OPTIONS` environment variable:
```shell
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.rmi.port=1099
-Dcom.sun.management.jmxremote.port=1099
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.access.file=/etc/jmxremote/jmxremote.access
-Dcom.sun.management.jmxremote.password.file=/etc/jmxremote/jmxremote.password
```
and mounts the `jmxremote.access` and `jmxremote.password` files as volumes from stores folder:
```yaml
volumes:
- ./stores/jmxremote.access:/etc/jmxremote/jmxremote.access
- ./stores/jmxremote.password:/etc/jmxremote/jmxremote.password
```
If you wish to keep that configuration, make sure that you can read and write the `/etc/jmxremote/jmxremote.password` and other users have no access to it.
An example on how to do that on Mac/Linux is by running the following command over :
```shell
chmod 0600 stores/jmxremote.password
```
Now you can invoke `docker-compose up` command:
```
docker-compose up --build
```
This will build a local containerize environment for you to inspect the application.
If you wish to deploy in other environments, you can always build and push a docker image using:
```
docker buildx build --platform=linux/amd64 --tag //tictactoe:1.0 . --no-cache
```