Skip to content
This repository was archived by the owner on Dec 10, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Docs: [https://surf-cloud-docs.netlify.app/](https://surf-cloud-docs.netlify.app

![logo](https://github.com/SLNE-Development/assets/blob/master/logos/surf-cloud/surf-cloud-logo-bg-removed.png?raw=true)

https://chatgpt.com/g/g-67f7a61dc2208191bea4663d0771d6dd-flyway-migration-generator

# TODO
## IntelliJ Plugin
Expand Down
174 changes: 174 additions & 0 deletions cert_new/INSTRUCTIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
# SSL Certificate Generation Guide for Netty Server and Clients

This guide explains how to generate and manage SSL/TLS certificates for your Netty-based server and
clients using OpenSSL. Properly generated certificates ensure secure communication between your
server and clients.

> **Note:** If you already have a server set up and only need to add a new client, you can skip directly
> to **[Step 4](#step-4-generate-client-certificates-repeatable-for-each-client)**. Ensure the following files are already present in your working directory:
> - `openssl.cnf`
> - `ca.key`
> - `ca.crt`

---

## Prerequisites

- Install [OpenSSL](https://slproweb.com/products/Win32OpenSSL.html) or use WSL/Git Bash.
- Ensure OpenSSL is available in your command prompt:

```bash
openssl version
```

---

## Step-by-Step Guide

### Step 1: Create an OpenSSL Configuration File (`openssl.cnf`)

Create a file named `openssl.cnf` in your working directory:

```ini
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no

[ req_distinguished_name ]
C = DE
ST = Remote
L = Internet
O = Surf Cloud
CN = YOUR_SERVER_IP_OR_DNS

[ v3_req ]
subjectAltName = @alt_names
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth

[ alt_names ]
IP.1 = YOUR_SERVER_IP
DNS.1 = YOUR_SERVER_DNS
```

Replace `YOUR_SERVER_IP` and `YOUR_SERVER_DNS` with your actual server IP address and DNS name.

Example:

```ini
CN = 192.168.1.23

[ alt_names ]
IP.1 = 192.168.1.23
DNS.1 = myserver.local
```

---

### Step 2: Generate Your Own Certificate Authority (CA)

Run the following commands once to create your CA:

```bash
openssl genrsa -out ca.key 2048

openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt -subj "/C=DE/ST=Remote/L=Internet/O=Surf Cloud/CN=SurfCloud CA"
```

**Important:**

- `ca.key`: Private key of your CA (keep this secret and safe).
- `ca.crt`: Public certificate of your CA (clients and server use this to establish trust).

---

### Step 3: Generate Server Certificate

```bash
# Generate private key
openssl genrsa -out server.key 2048

# Generate CSR (Certificate Signing Request)
openssl req -new -key server.key -out server.csr -config openssl.cnf

# Sign CSR with your CA
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -extfile openssl.cnf -extensions v3_req
```

**Files produced:**

- `server.key`: Server's private key (use on your Netty server).
- `server.crt`: Server's signed certificate (distribute to clients).

---

### Step 4: Generate Client Certificates (repeatable for each client)

Modify `openssl.cnf` by changing the `CN` to your client name (`client01`, `client02`, etc.):

```ini
CN = test-server01
```

Then run:

```bash
openssl genrsa -out client.key 2048

openssl req -new -key client.key -out client.csr -config openssl.cnf

openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365 -extfile openssl.cnf -extensions v3_req
```

**Files produced:**

- `client.key`: Client's private key (keep secret and only on the client).
- `client.crt`: Client's signed certificate (put this on your server to authenticate the
client).

---

## File Management

### Files to Keep and Their Usage

| File | Purpose | Store on |
|--------------|----------------------------------------------|--------------------------------------|
| `ca.key` | CA private key (needed for signing) | Secure offline storage (never share) |
| `ca.crt` | CA certificate (trusted by all participants) | Server and Clients |
| `server.key` | Server private key | Server (secure) |
| `server.crt` | Server certificate (signed by CA) | Server (send to clients) |
| `client.key` | Client private key | Client (secure) |
| `client.crt` | Client certificate (signed by CA) | Server (trust this certificate) |

### Directory Structure

**On Server:**

```
certificates/
├── server.key
├── server.crt
└── ca.crt
```

**On Client:**

```
certificates/
├── client.key
├── client.crt
└── ca.crt
```

---

## Common Errors and Fixes

- **Hostname/IP undefined:** Ensure your server certificate includes the correct IP/DNS in SAN.
- **certificate_unknown:** Ensure the client certificate is correctly placed in
`certificates/clients/` and signed by the CA.

---
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package dev.slne.surf.cloud.api.common.event.player.connection

import dev.slne.surf.cloud.api.common.event.player.CloudPlayerEvent
import dev.slne.surf.cloud.api.common.player.CloudPlayer
import java.io.Serial

class CloudPlayerDisconnectFromNetworkEvent(source: Any, player: CloudPlayer) :
CloudPlayerEvent(source, player) {
companion object {
@Serial
private const val serialVersionUID: Long = 1730514074081406974L
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx

import dev.slne.surf.bytebufserializer.KBufSerializer
import dev.slne.surf.cloud.api.common.netty.protocol.buffer.SurfByteBuf
import dev.slne.surf.cloud.api.common.util.annotation.InternalApi

@InternalApi
abstract class CloudBufSerializer<T> : KBufSerializer<T, SurfByteBuf> {
override val bufClass = SurfByteBuf::class
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx

import dev.slne.surf.bytebufserializer.Buf
import dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.adventure.AdventureComponentSerializer
import dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.adventure.AdventureKeySerializer
import dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.adventure.AdventureSoundSerializer
import dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.java.BitSetSerializer
import dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.java.Inet4AddressSerializer
import dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.java.InetSocketAddressSerializer
import dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.java.URISerializer
import dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.java.UUIDSerializer
import dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.java.UtfStringSerializer
import dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.java.ZonedDateTimeSerializer
import dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.kotlin.DurationSerializer
import dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.nbt.CompoundTagSerializer
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.contextual

object SurfCloudBufSerializer {
val serializerModule = SerializersModule {
// Adventure
contextual(AdventureKeySerializer)
contextual(AdventureSoundSerializer)
contextual(AdventureComponentSerializer)

// Java
contextual(UUIDSerializer)
contextual(BitSetSerializer)
contextual(UtfStringSerializer)
contextual(URISerializer)
contextual(InetSocketAddressSerializer)
contextual(ZonedDateTimeSerializer)
contextual(Inet4AddressSerializer)

// Kotlin
contextual(DurationSerializer)

// NBT
contextual(CompoundTagSerializer)
}

val serializer = Buf(serializerModule)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.adventure

import dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.CloudBufSerializer
import dev.slne.surf.cloud.api.common.netty.protocol.buffer.SurfByteBuf
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import net.kyori.adventure.text.Component

typealias SerializableComponent = @Serializable(with = AdventureComponentSerializer::class) Component

object AdventureComponentSerializer : CloudBufSerializer<Component>() {
override val descriptor = PrimitiveSerialDescriptor("Component", PrimitiveKind.STRING)

override fun serialize0(
buf: SurfByteBuf,
value: Component
) {
buf.writeComponent(value)
}

override fun deserialize0(buf: SurfByteBuf): Component {
return buf.readComponent()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.adventure

import dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.CloudBufSerializer
import dev.slne.surf.cloud.api.common.netty.protocol.buffer.SurfByteBuf
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import net.kyori.adventure.key.Key

typealias SerializableKey = @Serializable(with = AdventureKeySerializer::class) Key

object AdventureKeySerializer : CloudBufSerializer<Key>() {
override val descriptor = PrimitiveSerialDescriptor("Key", PrimitiveKind.STRING)

override fun serialize0(
buf: SurfByteBuf,
value: Key
) {
buf.writeKey(value)
}

override fun deserialize0(buf: SurfByteBuf): Key {
return buf.readKey()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.adventure

import dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.CloudBufSerializer
import dev.slne.surf.cloud.api.common.netty.protocol.buffer.SurfByteBuf
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.descriptors.element
import net.kyori.adventure.sound.Sound

typealias SerializableSound = @Serializable(with = AdventureSoundSerializer::class) Sound

object AdventureSoundSerializer : CloudBufSerializer<Sound>() {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Sound") {
element<Sound.Source>("source")
element<Float>("volume")
element<Float>("pitch")
element<Long?>("seed")
element<String>("name")
}

override fun serialize0(
buf: SurfByteBuf,
value: Sound
) {
buf.writeSound(value)
}

override fun deserialize0(buf: SurfByteBuf): Sound {
return buf.readSound()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.java

import dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.CloudBufSerializer
import dev.slne.surf.cloud.api.common.netty.protocol.buffer.SurfByteBuf
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.descriptors.element
import java.util.*

typealias SerializableBitSet = @Serializable(with = BitSetSerializer::class) BitSet

object BitSetSerializer : CloudBufSerializer<BitSet>() {
override val descriptor = buildClassSerialDescriptor("BitSet") {
element<LongArray>("longArray")
}

override fun serialize0(
buf: SurfByteBuf,
value: BitSet
) {
buf.writeBitSet(value)
}

override fun deserialize0(buf: SurfByteBuf): BitSet {
return buf.readBitSet()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.java

import dev.slne.surf.cloud.api.common.netty.network.codec.kotlinx.CloudBufSerializer
import dev.slne.surf.cloud.api.common.netty.protocol.buffer.SurfByteBuf
import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.ByteArraySerializer
import kotlinx.serialization.descriptors.SerialDescriptor
import java.net.Inet4Address

typealias SerializableInet4Address = @Serializable(with = Inet4AddressSerializer::class) Inet4Address

object Inet4AddressSerializer: CloudBufSerializer<Inet4Address>() {
override val descriptor = SerialDescriptor("Inet4Address", ByteArraySerializer().descriptor)

override fun serialize0(
buf: SurfByteBuf,
value: Inet4Address
) {
buf.writeInet4Address(value)
}

override fun deserialize0(buf: SurfByteBuf): Inet4Address {
return buf.readInet4Address()
}
}
Loading