Skip to content
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
84 changes: 44 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,97 +2,101 @@
[![PHP-CS-Fixer](https://github.com/Prestige-Solution/ts-x-php-framework/actions/workflows/phpcsfixer.yml/badge.svg?branch=main)](https://github.com/Prestige-Solution/ts-x-php-framework/actions/workflows/phpcsfixer.yml)
[![PHPUnit](https://github.com/Prestige-Solution/ts-x-php-framework/actions/workflows/phpunit.yml/badge.svg?branch=main)](https://github.com/Prestige-Solution/ts-x-php-framework/actions/workflows/phpunit.yml)
![Coverage](doc/coverage/coverage-badge.svg)

> [!CAUTION]
> **_IMPORTANT CHANGE_**<br>
> With Version 3.x we refactored to integrate phpseclib3. This changes affects how TCP connections are established.
> The "raw" mode was removed, and the support for only ssh mode was established to handel Teamspeak 3 and Teamspeak 6 Server API connections.

> Starting with Version 3.x, the framework has been refactored to integrate `phpseclib3`. These changes affect how TCP connections are established.
> The "raw" mode has been removed, and only SSH mode is supported to handle TeamSpeak 3 and TeamSpeak 6 Server API connections.

The X stands for a non-specific Teamspeak Server Version. So we would handle all current and future Versions from a Teamspeak Server.
The "X" stands for a non-version-specific TeamSpeak server implementation, allowing support for all current and future versions of TeamSpeak Server.

Unfortunately, the original repository is no longer up to date and has not been maintained for 3 years. This is the reason why this project is being created. <br>
The main goal is to bring the framework up to date and to equip it with extended unit tests which can also be carried out with tests for a live server. <br>
The ideal is that this version can be integrated into your own project and the main functionalities can be tested with your Teamspeak server.
As the original repository is no longer maintained, this project was created to bring the framework up to date, ensure PHP 8.x compatibility, and provide extensive unit test suites that can also be executed against a live server.

---

# Installation
With the Refactoring at Version 3.x, the Framework has a lot of changes. But most functionalities and namespaces are the same.
With the refactoring in version 3.x, the framework underwent substantial internal changes, while preserving most functionality and public namespaces.

**PHP Required Extensions**<br>
``apt install php8.3 php8.3-{common,mbstring,ssh2} -y``
**Required PHP Extensions**<br>
`apt install php8.3 php8.3-{common,mbstring,ssh2} -y`

**Via Composer**<br>
Current Version:<br>
``composer require prestige-solution/ts-x-php-framework``<br><br>
or with a specific release<br>
``composer require prestige-solution/ts-x-php-framework:latest``<br>
``composer require prestige-solution/ts-x-php-framework:3.0.0-beta``<br><br>
or with a specific branch<br>
``composer require prestige-solution/ts-x-php-framework:dev-ts-x-refactoring-dev``
`composer require prestige-solution/ts-x-php-framework`

Or with a specific release:<br>
`composer require prestige-solution/ts-x-php-framework:latest`<br>
`composer require prestige-solution/ts-x-php-framework:3.0.0-beta`

Or with a specific branch:<br>
`composer require prestige-solution/ts-x-php-framework:dev-ts-x-refactoring-dev`

---

## If your teamspeak 3 server is not running with version 3.x, check the rsa host key situation
Check out the documentation [make-ts3-ssh-compatible.md](doc/docker/make-ts3-ssh-compatible.md)<br>
There you can find instructions to set up a compatible rsa host key. It should work with docker and non-docker versions.
## If your TeamSpeak 3 server is not running with version 3.x, check the RSA host key configuration
See [make-ts3-ssh-compatible.md](doc/docker/make-ts3-ssh-compatible.md) for instructions on setting up a compatible RSA host key. It supports both Docker and non-Docker setups.

# New test routines for future developments and improvements with live server testing
# Test Routines for Live Server Testing
**<u>Prepare your Environment</u>**<br>
Before you start UnitTests, make sure that you have set the environment variables. You find more information's at [testing-live-server](doc/testing-live-server.md)
Before running unit tests, ensure that all required environment variables are set. For more details, see [testing-live-server](doc/testing-live-server.md).

**<u>Permissions for Query User</u>**<br>
The best way to test all functionalities is to use the serveradmin query user. <br>
The serveradmin is != Server Admin there you can find in your Teamspeak Client UI. <br>
The recommended way to test all functionality is using the `serveradmin` query user.<br>
Note: `serveradmin` is distinct from the Server Admin group found in the TeamSpeak client UI:

| serveradmin (Query) | Server Admin (GUI) |
|-------------------------------------|------------------------------------|
| Max. permission value: 100 (=grant) | Max. permission value: 75 (=grant) |

You can find more information in the Documentation [testing-live-server](doc/testing-live-server.md)
For further details, see [testing-live-server](doc/testing-live-server.md).

**<u>Additional Node</u>** <br>
- We know the serveradmin (query user) is a high-security risk if you use it over the internet. We would try to find a better solution with SSH public key authentication. <br>
- Currently, you can improve fail2ban, query_ip_whitelist and query_ip_blacklist.
**<u>Additional Notes</u>** <br>
- Using `serveradmin` credentials over public networks poses a security risk. Support for SSH public key authentication is planned.
- In the meantime, protect your instance using `fail2ban`, `query_ip_whitelist`, and `query_ip_blacklist`.

**<u>Run Tests</u>**<br>
To run all tests use `composer test`. <br>
To run all tests, execute `composer test`.

---
---

# Build Factory URI
## Default URI Options
| Options | Default Value |
| Option | Default Value |
|----------|---------------|
| timeout | 10 |

If you build the serverquery without the above parameter, then their options will be set by default. <br>
**Note:** don't set timeout to 0. Further Information's at [php.net](https://www.php.net/manual/de/function.stream-select.php)
If you build the ServerQuery connection without specifying the parameter above, default values will be applied.<br>
**Note:** Do not set `timeout` to 0. For more information, see [php.net stream_select](https://www.php.net/manual/de/function.stream-select.php).

## Examples
- URI Example
- URI Example:
```php
'serverquery://<user>:<pass>@<host>:<port>/?server_port=9987&no_query_clients=0&timeout=30&nickname=<bot_name>'
```

- Contains Username or Password special chars like ``+`` then you can use
- Verify your host with a fingerprint:
```php
'serverquery://<user>:<pass>@<host>:<port>/?server_port=9987&no_query_clients=0&timeout=30&nickname=<bot_name>&fingerprint=<fingerprint>'
```

- If your username or password contains special characters such as `+`, use `rawurlencode()`:
```php
'serverquery://'.rawurlencode(<user>).':'.rawurlencode(<password>) .'@<host>:<port>/?server_port=9987&no_query_clients=0&timeout=30'
'serverquery://' . rawurlencode($user) . ':' . rawurlencode($password) . '@<host>:<port>/?server_port=9987&no_query_clients=0&timeout=30'
```
In my opinion, you should **don't use specials chars**. Better, create a new QueryLogin Password and / or Username.
*Recommendation:* Avoid special characters in ServerQuery passwords and usernames where possible by generating plain alphanumeric credentials.

- You can use IPv4, IPv6 or DNS. Implement the following Example in your Project.
- Support IPv4, IPv6, or hostnames:
```php
if (filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) || filter_var(gethostbyname($host), FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
$validatedHost = $host;
} elseif (filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) || filter_var(gethostbyname($host), FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
$validatedHost = '['.$host.']';
$validatedHost = '[' . $host . ']';
} else {
return false;
}
```

---

# Important note
We have no intention of abandoning the original repository altogether. We will keep the namespace so that an update to the original PlanetTeamspeak repository can be considered as far as possible and the Support from the Maintainer is back.
# Important Note
We have no intention of abandoning compatibility with the original upstream repository. The namespace is preserved so that integration with the original PlanetTeamspeak repository remains possible if upstream maintenance resumes.
40 changes: 23 additions & 17 deletions doc/docker/make-ts3-ssh-compatible.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Teamspeak 3 and Teamspeak 6 SSH Compatible
## Teamspeak 3 Server
# TeamSpeak 3 and TeamSpeak 6 SSH Compatibility

## TeamSpeak 3 Server
### docker-compose.yml
```yaml
services:
Expand All @@ -8,32 +9,36 @@ services:
container_name: teamspeak-server
ports:
- "9987:9987/udp" # Voice
- "10011:10011" # Serverquery
- "10022:10022" # ssh query if binary support
- "30033:30033" # Filetransfer
- "10011:10011" # ServerQuery
- "10022:10022" # SSH ServerQuery (if supported by binary)
- "30033:30033" # File transfer
volumes:
- ./data:/var/ts3server # Persistente Daten creates automatically
- ./data:/var/ts3server # Persistent data directory created automatically
environment:
TS3SERVER_LICENSE: accept
TS3SERVER_QUERY_PROTOCOLS: "raw,ssh"
TS3SERVER_QUERY_SSH_PORT: "10022"
TS3SERVER_SERVERADMIN_PASSWORD: abc123
#if you would use a seperate database with postgres
# If using a separate PostgreSQL database:
#TS3SERVER_DB_PLUGIN: ts3db_postgresql
#TS3SERVER_DB_HOST: '127.0.0.1'
#TS3SERVER_DB_USER: 'query user'
#TS3SERVER_DB_PASSWORD: 'query user password' #You can set this option at anytime. During start the password will be changed during server start.
#TS3SERVER_DB_PASSWORD: 'query user password' # Can be updated at any time; applied during server startup.
#TS3SERVER_DB_NAME: 'database name'
#TS3SERVER_DB_PORT: 5432 # optional, Standard: 5432
#TS3SERVER_DB_PORT: 5432 # Optional, default: 5432
restart: unless-stopped
```

### Setup a ssh_rsa_host_key
go to ``ts3-docker/data`` and run ``ssh-keygen -t rsa -b 4096 -m PEM -f ssh_host_rsa_key -N ""`` <br>
This will create a compatible ssh_rsa_host_key for the teamspeak 3 server. <br>
### Set Up an RSA Host Key (`ssh_host_rsa_key`)
Navigate to `ts3-docker/data` and generate the RSA key pair:
```shell
ssh-keygen -t rsa -b 4096 -m PEM -f ssh_host_rsa_key -N ""
```
This creates a compatible RSA host key for the TeamSpeak 3 server.

Start the server with ``docker-compose up -d``. The logs should not see ``creating QUERY_SSH_RSA_HOST_KEY file…`` <br>
Be sure the correct permissions are set for the ssh_rsa_host_key file.
Start the server using `docker-compose up -d`. The logs should not show `creating QUERY_SSH_RSA_HOST_KEY file…`.

Ensure that appropriate file permissions are set for the key files:
```shell
docker-compose up -d ts3
docker exec -it teamspeak-server sh -c "chmod 600 /var/ts3server/ssh_host_rsa_key && chmod 644 /var/ts3server/ssh_host_rsa_key.pub"
Expand All @@ -53,7 +58,8 @@ docker-compose restart ts3
│   └── ts3server.sqlitedb
└── docker-compose.yml
```
## Teamspeak 6 Server

## TeamSpeak 6 Server
```yaml
services:
teamspeak:
Expand All @@ -63,9 +69,9 @@ services:
ports:
- "9987:9987/udp" # Default voice port
- "30033:30033/tcp" # File transfer port
- "10022:10022/tcp" # (Optional) ServerQuery SSH port
- "10022:10022/tcp" # (Optional) ServerQuery SSH port
- "10080:10080/tcp" # (Optional) WebQuery port
- "5899:5899" # Websocket
- "5899:5899" # WebSocket
environment:
- TSSERVER_LICENSE_ACCEPTED=accept
- TSSERVER_DEFAULT_PORT=9987
Expand Down
64 changes: 34 additions & 30 deletions doc/testing-live-server.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,44 @@
Testing with Live or Development Server
==================
## Setup Environment
# Testing with a Live or Development Server

## Environment Setup

```shell
cp .env.testing.example .env.testing
```
Replace all `DEV_LIVE_SERVER_*` Variables with your Teamspeak Configuration

| Environment Variable | Description |
|-----------------------------------------------------|----------------------------------------------------------------------------------------------------------------------|
| DEV_LIVE_SERVER_AVAILABLE= | Activate Channel Tests (Default = false). At false all Channel Tests will be skipped |
| DEV_LIVE_SERVER_HOST= | Your Host Address (Recommended: IPv4) |
| DEV_LIVE_SERVER_QUERY_PORT= | ssh = 10022 |
| DEV_LIVE_SERVER_QUERY_USER= | Your Query Username |
| DEV_LIVE_SERVER_QUERY_USER_PASSWORD= | Password for the Query User |
| DEV_LIVE_SERVER_UNIT_TEST_CHANNEL= | Setup a Channelname for Channel Tests. The Live Server Tests will create channels under this configured Channelname* |
| DEV_LIVE_SERVER_UNIT_TEST_USER_ACTIVE= | Activate User Tests (Default = false). At false all User Tests will be skipped |
| DEV_LIVE_SERVER_UNIT_TEST_USER=UnitTestUser | Setup a Teamspeak Testclient. It will be use for Client Tests |
| DEV_LIVE_SERVER_UNIT_TEST_SIGNALS= | Test Signals. Default = false. NOTE: This Test has a very long Test duration. |
| DEV_LIVE_SERVER_UNIT_TEST_USER_EXTEND=UnitTestUser2 | Define a second TestUser |

Replace all `DEV_LIVE_SERVER_*` variables with your TeamSpeak configuration:

| Environment Variable | Description |
|-----------------------------------------------------|---------------------------------------------------------------------------------------------------------------|
| DEV_LIVE_SERVER_AVAILABLE= | Enable channel tests (default: `false`). When set to `false`, all channel tests are skipped. |
| DEV_LIVE_SERVER_HOST= | Your host address (recommended: IPv4). |
| DEV_LIVE_SERVER_QUERY_PORT= | SSH ServerQuery port (default: `10022`). |
| DEV_LIVE_SERVER_QUERY_USER= | Your ServerQuery username. |
| DEV_LIVE_SERVER_QUERY_USER_PASSWORD= | Password for the ServerQuery user. |
| DEV_LIVE_SERVER_UNIT_TEST_CHANNEL= | Channel name for channel tests. Live server tests will create subchannels under this configured channel name. |
| DEV_LIVE_SERVER_UNIT_TEST_USER_ACTIVE= | Enable user tests (default: `false`). When set to `false`, all user tests are skipped. |
| DEV_LIVE_SERVER_UNIT_TEST_USER=UnitTestUser | Configure a TeamSpeak test client used for client tests. |
| DEV_LIVE_SERVER_UNIT_TEST_SIGNALS= | Enable signal tests (default: `false`). Note: This test suite has a long runtime. |
| DEV_LIVE_SERVER_UNIT_TEST_USER_EXTEND=UnitTestUser2 | Define a second test user. |
| DEV_LIVE_SERVER_UNIT_TEST_SERVER_PORT= | Extended Unit Tests with additional server port |
| DEV_LIVE_SERVER_UNIT_TEST_SERVER_QUERY_LOGIN_NAME= | Custom Bot Name |
| DEV_LIVE_SERVER_UNIT_TEST_SERVER_HOST_KEY= | Yor Host Fingerprint |

### Important Configuration
* Setup your Testserver. You can use Templates from ![make-ts3-ssh-compatible](../doc/docker/make-ts3-ssh-compatible.md). Remember to create a new RSA Hostkey at Teamspeak 3 Server.
* Create a new Channel with Channelname ``UnitTest``
* Rename the Server Name to ``UnitTestServer``
* Set up your test server. You can use templates from [make-ts3-ssh-compatible](docker/make-ts3-ssh-compatible.md). Remember to create a new RSA host key on the TeamSpeak 3 server.
* Create a new channel named `UnitTest`.
* Rename the virtual server to `UnitTestServer`.

### Scenario 1: Use the serveradmin query (RECOMMENDED)
If you want to test all functions without permissions issues, you should use the serveradmin query.
When you want to migrate from Teamspeak Server 3 to 6, you need the serveradmin query, otherwise you run in permission issues.
If you want to test both Servers at the same time, you can set the same serveradmin password for both Servers.
### Scenario 1: Use the serveradmin Query User (Recommended)
To test all functionality without permission issues, use the `serveradmin` query user.
When migrating from TeamSpeak Server 3 to 6, using `serveradmin` is required to avoid permission issues.
If you want to test both servers simultaneously, you can set the same `serveradmin` password on both servers.

### Scenario 2: Set up an individual query Servergroup
If you want to test or use a specific Bot Identity, you have to create a new Servergroup for the bot.
You can define all permissions there you want but be sure the permissions have enough power. Otherwise, you get insufficient_permissions errors.
### Scenario 2: Set Up a Custom ServerQuery Server Group
If you want to test using a specific bot identity, create a dedicated server group for the bot.
You can assign any desired permissions, but ensure the group has sufficient permission power. Otherwise, `insufficient_permissions` errors will occur.

### Important Notes
If you run these Live Server Tests, the Clients see massive Server Log entrys with Anti-Flood errors. <br>
The test is rapid with a lot of connections from the bot (one connection and disconnection for each test). <br>
The Serveradministrator has no Anti-Flood Permissions, so maybe you as an Administrator can't see these entrys.
When running live server tests, clients may notice numerous anti-flood warnings in the server log.<br>
The test suite runs rapidly with frequent connections from the bot (establishing and closing a connection for each test).<br>
The `serveradmin` account bypasses anti-flood restrictions, so administrators might not see these warnings in their client view.
Loading