Improve properties validation in openvidu-server

pull/431/head
micaelgallego 2020-03-30 02:33:36 +02:00
parent 90c84eb41a
commit 30ceb1681e
8 changed files with 656 additions and 688 deletions

View File

@ -20,7 +20,7 @@ services:
- OPENVIDU_PUBLICURL= - OPENVIDU_PUBLICURL=
- OPENVIDU_RECORDING=true - OPENVIDU_RECORDING=true
- OPENVIDU_RECORDING_PATH=${OPENVIDU_RECORDING_FOLDER} - OPENVIDU_RECORDING_PATH=${OPENVIDU_RECORDING_FOLDER}
- KMS_URIS="[\"ws://127.0.0.1:8888/kurento\"]" - KMS_URIS=["ws://localhost:8888/kurento"]
- COTURN_IP=${OPENVIDU_DOMAIN_OR_PUBLIC_IP} - COTURN_IP=${OPENVIDU_DOMAIN_OR_PUBLIC_IP}
- COTURN_REDIS_IP=127.0.0.1 - COTURN_REDIS_IP=127.0.0.1
- LOGGING_LEVEL_ROOT=${OV_CE_DEBUG_LEVEL:-INFO} - LOGGING_LEVEL_ROOT=${OV_CE_DEBUG_LEVEL:-INFO}
@ -29,7 +29,8 @@ services:
image: kurento/${KMS_IMAGE:-kurento-media-server-dev:6.13} image: kurento/${KMS_IMAGE:-kurento-media-server-dev:6.13}
restart: on-failure restart: on-failure
network_mode: host network_mode: host
ulimits: -1 ulimits:
core: -1
environment: environment:
- KMS_EXTERNAL_ADDRESS=auto - KMS_EXTERNAL_ADDRESS=auto
- KMS_MIN_PORT=40000 - KMS_MIN_PORT=40000

View File

@ -31,6 +31,8 @@ Open ports:
- 57001 - 65535 UDP: Used by TURN Server to stablish media connections. - 57001 - 65535 UDP: Used by TURN Server to stablish media connections.
- 57001 - 65535 TCP: Used by TURN Server to stablish media connections. - 57001 - 65535 TCP: Used by TURN Server to stablish media connections.
It is important to have a **domain name** pointing to the machine where you are are going to deploy OpenVidu. The platform is deployed using https because is mandatory to use WebRTC. Then, if you do not have a domain name, an ugly warning will appear to your users when enter to your site. And, of course, you can suffer a man in the middle attack. You don't need a valid SSL certificate as one can be created by Let's Encrypt in the installation process.
## 2. Deployment Instructions ## 2. Deployment Instructions
### Clone Repository ### Clone Repository
@ -48,9 +50,11 @@ $ cd openvidu-server/docker/openvidu-docker-compose
OpenVidu configuration is specified in the `.env` file with environment variables. OpenVidu configuration is specified in the `.env` file with environment variables.
**YOU MUST** specify the **domain or public IP** of the machine and the OpenVidu **secret**. **YOU MUST** specify the **DOMAIN_OR_PUBLIC_IP** of the machine and the **OPENVIDU_SECRET**.
All other values have sane defaults. If you have a domain name, generate a certificate with Let's Encrypt or put your own certificate.
All other config properties have sane defaults.
``` ```
# OpenVidu configuration # OpenVidu configuration
@ -104,7 +108,7 @@ services:
- OPENVIDU_SECRET=${OPENVIDU_SECRET} - OPENVIDU_SECRET=${OPENVIDU_SECRET}
``` ```
You can disable it deleting the file `docker-compose.override.yml` (or renaming it in case you want to enable again in the future). You can disable OpenVidu Call application deleting the file `docker-compose.override.yml` (or renaming it in case you want to enable again in the future).
You can configure other dockerized application if you want updating the content of `docker-compose.override.yml` with the following requirements: You can configure other dockerized application if you want updating the content of `docker-compose.override.yml` with the following requirements:
* You have to bind your application port to 5442 in the host, as this port is used by NGINX to publish your app in port 443. * You have to bind your application port to 5442 in the host, as this port is used by NGINX to publish your app in port 443.
@ -130,12 +134,18 @@ Creating openvidu-docker-compose_redis_1 ... done
Creating openvidu-docker-compose_openvidu-server_1 ... done Creating openvidu-docker-compose_openvidu-server_1 ... done
``` ```
Then, you should check openvidu-server logs to verify if all is configured and working as expected with the following command: Then, you should check openvidu-server logs to verify if all is configured and working as expected. Use the following command:
``` ```
$ docker-compose logs -f openvidu-server $ docker-compose logs -f openvidu-server
``` ```
For your convenience, you can execute the following script to perform these two commands (and stop previously started OpenVidu platform, just in case)
```
$ ./openvidu-restart.sh
```
When OpenVidu Platform is ready you will see this message: When OpenVidu Platform is ready you will see this message:
``` ```
---------------------------------------------------- ----------------------------------------------------
@ -173,9 +183,9 @@ To change the configuration follow this steps:
> TODO: Review that changing domain name with CERTIFICATE_TYPE=letsencrypt regenerates the certificate. > TODO: Review that changing domain name with CERTIFICATE_TYPE=letsencrypt regenerates the certificate.
### What to do if OpenVidu is not working ## 3. What to do if OpenVidu is not working
#### Show service logs ### Show service logs
Take a look to service logs to see what happen. First, see openvidu-server logs: Take a look to service logs to see what happen. First, see openvidu-server logs:
@ -196,14 +206,36 @@ $ docker-compose logs -f coturn
$ docker-compose logs -f redis $ docker-compose logs -f redis
$ docker-compose logs -f app $ docker-compose logs -f app
``` ```
### Review the configuration
#### Updating the log level of the services Sometimes, we can have a typo when writing a property name. For this reason, openvidu-server print in the log all the configuration properties you are configured in the file and the default values for all other config properties. In that way, you can double check what openvidu-server *see*.
##### Openvidu Server Level logs If `openvidu-server` detects some error, it will show it in the log.
If it was necessary to change the level of the kms logs. In the .en file we go to the section "Openvidu Server Level logs" and change the variable `OV_CE_DEBUG_LEVEL`
##### Kurento Media Server Level logs ```
If it was necessary to change the level of the kms logs. In the .en file we go to the section "Kurento Media Server Level logs" and change the variable `KMS_DEBUG_LEVEL` for more information https://doc-kurento.readthedocs.io/en/stable/features/logging.html Configuration properties
---------------------
* CERTIFICATE_TYPE=selfsigned
* OPENVIDU_CDR=false
* OPENVIDU_CDR_PATH=log
* OPENVIDU_DOMAIN_OR_PUBLIC_IP=d
* OPENVIDU_RECORDING=true
* OPENVIDU_RECORDING_AUTOSTOP-TIMEOUT=120
* OPENVIDU_RECORDING_COMPOSED-URL=
### Use other Kurento Media Server docker image ...
If is necessaries change the Kurento Media Server image, go to the Kurento Media Server image section in the .env file and change the variable `KMS_IMAGE` with the new image that your want use ```
### Change log level of the services
#### Openvidu Server Level logs
To change the level of `openvidu-server` logs change the property `OV_CE_DEBUG_LEVEL`.
#### Kurento Media Server Level logs
To change the level of Kurento Media Server `kms` logs change the property `KMS_DEBUG_LEVEL`. For more information about possible values visit https://doc-kurento.readthedocs.io/en/stable/features/logging.html
### Change Kurento Media Server docker image
OpenVidu and Kurento Media Server evolves at different rithm. Sometimes, it is possible that a new KMS is released but OpenVidu is not still updated. In that case, in case you hit a bug and that bug is solved in last KMS version, you can test if updating only KMS is working for you. `KMS_IMAGE` property allows you to specify the new KMS image.

View File

@ -19,8 +19,12 @@ package io.openvidu.server;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.Semaphore;
import org.bouncycastle.util.Arrays;
import org.kurento.jsonrpc.internal.server.config.JsonRpcConfiguration; import org.kurento.jsonrpc.internal.server.config.JsonRpcConfiguration;
import org.kurento.jsonrpc.server.JsonRpcConfigurer; import org.kurento.jsonrpc.server.JsonRpcConfigurer;
import org.kurento.jsonrpc.server.JsonRpcHandlerRegistry; import org.kurento.jsonrpc.server.JsonRpcHandlerRegistry;
@ -31,6 +35,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.DependsOn; import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
@ -41,6 +46,7 @@ import io.openvidu.server.cdr.CDRLoggerFile;
import io.openvidu.server.cdr.CallDetailRecord; import io.openvidu.server.cdr.CallDetailRecord;
import io.openvidu.server.config.HttpHandshakeInterceptor; import io.openvidu.server.config.HttpHandshakeInterceptor;
import io.openvidu.server.config.OpenviduConfig; import io.openvidu.server.config.OpenviduConfig;
import io.openvidu.server.config.OpenviduConfig.Error;
import io.openvidu.server.core.SessionEventsHandler; import io.openvidu.server.core.SessionEventsHandler;
import io.openvidu.server.core.SessionManager; import io.openvidu.server.core.SessionManager;
import io.openvidu.server.core.TokenGenerator; import io.openvidu.server.core.TokenGenerator;
@ -214,69 +220,82 @@ public class OpenViduServer implements JsonRpcConfigurer {
} }
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
checkConfigProperties();
log.info("Using /dev/urandom for secure random generation"); log.info("Using /dev/urandom for secure random generation");
System.setProperty("java.security.egd", "file:/dev/./urandom"); System.setProperty("java.security.egd", "file:/dev/./urandom");
SpringApplication.run(OpenViduServer.class, args); SpringApplication.run(OpenViduServer.class, Arrays.append(args, "--spring.main.banner-mode=off"));
}
private static void checkConfigProperties() throws InterruptedException {
ConfigurableApplicationContext app = SpringApplication.run(OpenviduConfig.class,
new String[] { "--spring.main.web-application-type=none" });
OpenviduConfig config = app.getBean(OpenviduConfig.class);
List<Error> errors = config.getConfigErrors();
if (!errors.isEmpty()) {
// @formatter:off
String msg = "\n\n\n" + " Configuration errors\n" + " --------------------\n" + "\n";
for (Error error : config.getConfigErrors()) {
msg += " * Property " + config.getPropertyName(error.getProperty());
if (error.getValue() == null || error.getValue().equals("")) {
msg += " is not set. ";
} else {
msg += "=" + error.getValue() + ". ";
}
msg += error.getMessage() + "\n";
}
msg += "\n" + "\n" + " Fix config errors\n" + " ---------------\n" + "\n"
+ " 1) Return to shell pressing Ctrl+C\n"
+ " 2) Set correct values in '.env' configuration file\n" + " 3) Restart OpenVidu with:\n"
+ "\n" + " $ ./openvidu-restart.sh\n" + "\n";
// @formatter:on
log.info(msg);
// Wait forever
new Semaphore(0).acquire();
} else {
String msg = "\n\n\n" + " Configuration properties\n" + " ----------------------\n" + "\n";
Map<String, String> configProps = config.getConfigProps();
List<String> configPropNames = new ArrayList<>(config.getUserProperties());
Collections.sort(configPropNames);
for(String property : configPropNames) {
String value = configProps.get(property);
msg += " * "+config.getPropertyName(property)+"="+(value == null? "": value)+"\n";
}
msg += "\n\n";
log.info(msg);
}
} }
@EventListener(ApplicationReadyEvent.class) @EventListener(ApplicationReadyEvent.class)
public void whenReady() { public void whenReady() {
String startMessage;
if(!config.getConfErrors().isEmpty()) {
// @formatter:off
startMessage =
"\n\n----------------------------------------------------\n" +
"\n"+
" Configuration errors\n" +
" --------------------\n" +
"\n";
for(String msg : config.getConfErrors()) {
startMessage += " * "+ msg + "\n";
}
startMessage += "\n"+
"\n"+
" Instructions\n" +
" ------------\n" +
"\n"+
" 1) Stop OpenVidu services with command:\n" +
"\n"+
" $ docker-compose down\n"+
"\n"+
" 2) Fix configuration errors in .env file.\n" +
"\n"+
" 3) Start OpenVidu services with command:\n"+
"\n"+
" $ docker-compose up -d\n"+
"\n"+
"----------------------------------------------------\n";
// @formatter:on
} else {
String dashboardUrl = httpUrl + "dashboard/"; String dashboardUrl = httpUrl + "dashboard/";
// @formatter:off // @formatter:off
startMessage = String msg = "\n\n----------------------------------------------------\n" + "\n"
"\n\n----------------------------------------------------\n" + + " OpenVidu Platform is ready!\n" + " ---------------------------\n" + "\n"
"\n"+ + " * OpenVidu Server: " + httpUrl + "\n" + "\n" + " * OpenVidu Dashboard: " + dashboardUrl + "\n"
" OpenVidu Platform is ready!\n" + + "\n" + "----------------------------------------------------\n";
" ---------------------------\n" +
"\n"+
" * OpenVidu Server: " + httpUrl + "\n"+
"\n"+
" * OpenVidu Dashboard: " + dashboardUrl + "\n"+
"\n"+
"----------------------------------------------------\n";
// @formatter:on // @formatter:on
}
log.info(startMessage); log.info(msg);
} }
} }

View File

@ -0,0 +1,41 @@
/*
* (C) Copyright 2017-2020 OpenVidu (https://openvidu.io)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package io.openvidu.server.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.info.BuildProperties;
import org.springframework.stereotype.Component;
@Component
public class OpenviduBuildConfig {
@Autowired
private BuildProperties buildProperties;
public String getOpenViduServerVersion() {
String v = this.buildProperties.get("version.openvidu.server");
if (v == null) {
v = this.getVersion();
}
return v;
}
public String getVersion() {
return this.buildProperties.getVersion();
}
}

View File

@ -22,6 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import io.openvidu.java.client.OpenViduRole; import io.openvidu.java.client.OpenViduRole;
import io.openvidu.server.OpenViduServer; import io.openvidu.server.OpenViduServer;
import io.openvidu.server.config.OpenviduBuildConfig;
import io.openvidu.server.config.OpenviduConfig; import io.openvidu.server.config.OpenviduConfig;
import io.openvidu.server.coturn.CoturnCredentialsService; import io.openvidu.server.coturn.CoturnCredentialsService;
import io.openvidu.server.coturn.TurnCredentials; import io.openvidu.server.coturn.TurnCredentials;
@ -35,6 +36,9 @@ public class TokenGeneratorDefault implements TokenGenerator {
@Autowired @Autowired
protected OpenviduConfig openviduConfig; protected OpenviduConfig openviduConfig;
@Autowired
protected OpenviduBuildConfig openviduBuildConfig;
@Override @Override
public Token generateToken(String sessionId, OpenViduRole role, String serverMetadata, public Token generateToken(String sessionId, OpenViduRole role, String serverMetadata,
KurentoTokenOptions kurentoTokenOptions) { KurentoTokenOptions kurentoTokenOptions) {
@ -43,7 +47,7 @@ public class TokenGeneratorDefault implements TokenGenerator {
token += "&token=" + IdentifierPrefixes.TOKEN_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase() token += "&token=" + IdentifierPrefixes.TOKEN_ID + RandomStringUtils.randomAlphabetic(1).toUpperCase()
+ RandomStringUtils.randomAlphanumeric(15); + RandomStringUtils.randomAlphanumeric(15);
token += "&role=" + role.name(); token += "&role=" + role.name();
token += "&version=" + openviduConfig.getOpenViduServerVersion(); token += "&version=" + openviduBuildConfig.getOpenViduServerVersion();
TurnCredentials turnCredentials = null; TurnCredentials turnCredentials = null;
if (this.coturnCredentialsService.isCoturnAvailable()) { if (this.coturnCredentialsService.isCoturnAvailable()) {
turnCredentials = coturnCredentialsService.createUser(); turnCredentials = coturnCredentialsService.createUser();

View File

@ -34,6 +34,7 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import io.openvidu.server.cdr.CDREventName; import io.openvidu.server.cdr.CDREventName;
import io.openvidu.server.config.OpenviduBuildConfig;
import io.openvidu.server.config.OpenviduConfig; import io.openvidu.server.config.OpenviduConfig;
/** /**
@ -50,12 +51,15 @@ public class ConfigRestController {
@Autowired @Autowired
private OpenviduConfig openviduConfig; private OpenviduConfig openviduConfig;
@Autowired
private OpenviduBuildConfig openviduBuildConfig;
@RequestMapping(value = "/openvidu-version", method = RequestMethod.GET) @RequestMapping(value = "/openvidu-version", method = RequestMethod.GET)
public String getOpenViduServerVersion() { public String getOpenViduServerVersion() {
log.info("REST API: GET /config/openvidu-version"); log.info("REST API: GET /config/openvidu-version");
return openviduConfig.getOpenViduServerVersion(); return openviduBuildConfig.getOpenViduServerVersion();
} }
@RequestMapping(value = "/openvidu-publicurl", method = RequestMethod.GET) @RequestMapping(value = "/openvidu-publicurl", method = RequestMethod.GET)
@ -96,7 +100,7 @@ public class ConfigRestController {
log.info("REST API: GET /config"); log.info("REST API: GET /config");
JsonObject json = new JsonObject(); JsonObject json = new JsonObject();
json.addProperty("version", openviduConfig.getVersion()); json.addProperty("version", openviduBuildConfig.getVersion());
JsonArray kmsUris = new JsonArray(); JsonArray kmsUris = new JsonArray();
openviduConfig.getKmsUris().forEach(uri -> kmsUris.add(uri)); openviduConfig.getKmsUris().forEach(uri -> kmsUris.add(uri));
json.add("kmsUris", kmsUris); json.add("kmsUris", kmsUris);

View File

@ -9,6 +9,7 @@ server.ssl.key-alias=openvidu-selfsigned
logging.level.root=info logging.level.root=info
spring.main.allow-bean-definition-overriding=true spring.main.allow-bean-definition-overriding=true
certificate.type=selfsigned
kms.uris=["ws://localhost:8888/kurento"] kms.uris=["ws://localhost:8888/kurento"]
openvidu.publicurl=local openvidu.publicurl=local