mirror of
https://github.com/ossrs/srs.git
synced 2025-02-12 19:31:53 +00:00
fix #211, support security allow/deny publish/play all/ip. 2.0.86
This commit is contained in:
parent
f8ec7c706d
commit
75f2607685
14 changed files with 348 additions and 4 deletions
|
@ -501,6 +501,7 @@ Supported operating systems and hardware:
|
|||
* 2013-10-17, Created.<br/>
|
||||
|
||||
## History
|
||||
* v2.0, 2015-01-02, hotfix [#211](https://github.com/winlinvip/simple-rtmp-server/issues/211), support security allow/deny publish/play all/ip. 2.0.86
|
||||
* v2.0, 2015-01-02, hotfix [#207](https://github.com/winlinvip/simple-rtmp-server/issues/207), trim the last 0 of log. 2.0.85
|
||||
* v2.0, 2014-01-02, fix [#158](https://github.com/winlinvip/simple-rtmp-server/issues/158), http-callback check http status code ok(200). 2.0.84
|
||||
* v2.0, 2015-01-02, hotfix [#216](https://github.com/winlinvip/simple-rtmp-server/issues/216), http-callback post in application/json content-type. 2.0.83
|
||||
|
|
29
trunk/conf/full.conf
Executable file → Normal file
29
trunk/conf/full.conf
Executable file → Normal file
|
@ -142,6 +142,35 @@ http_stream {
|
|||
vhost __defaultVhost__ {
|
||||
}
|
||||
|
||||
# the security to allow or deny clients.
|
||||
vhost security.srs.com {
|
||||
# security for host to allow or deny clients.
|
||||
# @see https://github.com/winlinvip/simple-rtmp-server/issues/211
|
||||
security {
|
||||
# whether enable the security for vhost.
|
||||
# default: off
|
||||
enabled on;
|
||||
# the security list, each item format as:
|
||||
# allow|deny publish|play all|<ip>
|
||||
# for example:
|
||||
# allow publish all;
|
||||
# deny publish all;
|
||||
# allow publish 127.0.0.1;
|
||||
# deny publish 127.0.0.1;
|
||||
# allow play all;
|
||||
# deny play all;
|
||||
# allow play 127.0.0.1;
|
||||
# deny play 127.0.0.1;
|
||||
# SRS apply the following simple strategies one by one:
|
||||
# 1. allow all if security disabled.
|
||||
# 2. default to deny all when security enabled.
|
||||
# 3. allow if matches allow strategy.
|
||||
# 4. deny if matches deny strategy.
|
||||
allow play all;
|
||||
allow publish all;
|
||||
}
|
||||
}
|
||||
|
||||
# the MR(merged-read) setting for publisher.
|
||||
# the MW(merged-write) settings for player.
|
||||
vhost mrw.srs.com {
|
||||
|
|
0
trunk/conf/realtime.conf
Executable file → Normal file
0
trunk/conf/realtime.conf
Executable file → Normal file
13
trunk/conf/security.deny.publish.conf
Normal file
13
trunk/conf/security.deny.publish.conf
Normal file
|
@ -0,0 +1,13 @@
|
|||
# security config for srs, allow play and deny publish.
|
||||
# @see https://github.com/winlinvip/simple-rtmp-server/issues/211#issuecomment-68507035
|
||||
# @see full.conf for detail config.
|
||||
|
||||
listen 1935;
|
||||
max_connections 1000;
|
||||
vhost __defaultVhost__ {
|
||||
security {
|
||||
enabled on;
|
||||
deny publish all;
|
||||
allow play all;
|
||||
}
|
||||
}
|
2
trunk/configure
vendored
2
trunk/configure
vendored
|
@ -389,7 +389,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
|||
"srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks"
|
||||
"srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge"
|
||||
"srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_avc_aac"
|
||||
"srs_app_recv_thread")
|
||||
"srs_app_recv_thread" "srs_app_security")
|
||||
APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh
|
||||
APP_OBJS="${MODULE_OBJS[@]}"
|
||||
fi
|
||||
|
|
|
@ -434,7 +434,8 @@ int SrsConfig::reload_conf(SrsConfig* conf)
|
|||
// always support reload without additional code:
|
||||
// chunk_size, ff_log_dir, max_connections,
|
||||
// bandcheck, http_hooks, heartbeat,
|
||||
// token_traverse, debug_srs_upnode
|
||||
// token_traverse, debug_srs_upnode,
|
||||
// security
|
||||
|
||||
// merge config: listen
|
||||
if (!srs_directive_equals(root->get("listen"), old_root->get("listen"))) {
|
||||
|
@ -1363,6 +1364,7 @@ int SrsConfig::check_config()
|
|||
&& n != "atc" && n != "atc_auto"
|
||||
&& n != "debug_srs_upnode"
|
||||
&& n != "mr" && n != "mw_latency" && n != "min_latency"
|
||||
&& n != "security"
|
||||
) {
|
||||
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
||||
srs_error("unsupported vhost directive %s, ret=%d", n.c_str(), ret);
|
||||
|
@ -1440,6 +1442,16 @@ int SrsConfig::check_config()
|
|||
return ret;
|
||||
}
|
||||
}*/
|
||||
} else if (n == "security") {
|
||||
for (int j = 0; j < (int)conf->directives.size(); j++) {
|
||||
SrsConfDirective* security = conf->at(j);
|
||||
string m = security->name.c_str();
|
||||
if (m != "enabled" && m != "deny" && m != "allow") {
|
||||
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
||||
srs_error("unsupported vhost security directive %s, ret=%d", m.c_str(), ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} else if (n == "transcode") {
|
||||
for (int j = 0; j < (int)conf->directives.size(); j++) {
|
||||
SrsConfDirective* trans = conf->at(j);
|
||||
|
@ -2456,6 +2468,43 @@ bool SrsConfig::get_vhost_edge_token_traverse(string vhost)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SrsConfig::get_security_enabled(string vhost)
|
||||
{
|
||||
SrsConfDirective* conf = get_vhost(vhost);
|
||||
|
||||
if (!conf) {
|
||||
return SRS_CONF_DEFAULT_SECURITY_ENABLED;
|
||||
}
|
||||
|
||||
SrsConfDirective* security = conf->get("security");
|
||||
if (!security) {
|
||||
return SRS_CONF_DEFAULT_SECURITY_ENABLED;
|
||||
}
|
||||
|
||||
conf = security->get("enabled");
|
||||
if (!conf || conf->arg0() != "on") {
|
||||
return SRS_CONF_DEFAULT_SECURITY_ENABLED;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SrsConfDirective* SrsConfig::get_security_rules(string vhost)
|
||||
{
|
||||
SrsConfDirective* conf = get_vhost(vhost);
|
||||
|
||||
if (!conf) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SrsConfDirective* security = conf->get("security");
|
||||
if (!security) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return security;
|
||||
}
|
||||
|
||||
SrsConfDirective* SrsConfig::get_transcode(string vhost, string scope)
|
||||
{
|
||||
SrsConfDirective* conf = get_vhost(vhost);
|
||||
|
|
|
@ -76,6 +76,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define SRS_CONF_DEFAULT_HTTP_HEAETBEAT_URL "http://"SRS_CONSTS_LOCALHOST":8085/api/v1/servers"
|
||||
#define SRS_CONF_DEFAULT_HTTP_HEAETBEAT_SUMMARIES false
|
||||
|
||||
#define SRS_CONF_DEFAULT_SECURITY_ENABLED false
|
||||
|
||||
#define SRS_CONF_DEFAULT_STATS_NETWORK_DEVICE_INDEX 0
|
||||
|
||||
#define SRS_CONF_DEFAULT_STAGE_PLAY_USER_INTERVAL_MS 10000
|
||||
|
@ -659,6 +661,16 @@ public:
|
|||
* all clients connected to edge must be tranverse to origin to verify.
|
||||
*/
|
||||
virtual bool get_vhost_edge_token_traverse(std::string vhost);
|
||||
// vhost security section
|
||||
public:
|
||||
/**
|
||||
* whether the secrity of vhost enabled.
|
||||
*/
|
||||
virtual bool get_security_enabled(std::string vhost);
|
||||
/**
|
||||
* get the security rules.
|
||||
*/
|
||||
virtual SrsConfDirective* get_security_rules(std::string vhost);
|
||||
// vhost transcode section
|
||||
public:
|
||||
/**
|
||||
|
@ -776,7 +788,7 @@ public:
|
|||
* @remark, we will use some variable, for instance, [vhost] to substitude with vhost.
|
||||
*/
|
||||
virtual std::string get_engine_output(SrsConfDirective* engine);
|
||||
// ingest section
|
||||
// vhost ingest section
|
||||
public:
|
||||
/**
|
||||
* get the ingest directives of vhost.
|
||||
|
|
|
@ -51,6 +51,7 @@ using namespace std;
|
|||
#include <srs_app_recv_thread.hpp>
|
||||
#include <srs_core_performance.hpp>
|
||||
#include <srs_kernel_utility.hpp>
|
||||
#include <srs_app_security.hpp>
|
||||
|
||||
// when stream is busy, for example, streaming is already
|
||||
// publishing, when a new client to request to publish,
|
||||
|
@ -81,6 +82,7 @@ SrsRtmpConn::SrsRtmpConn(SrsServer* srs_server, st_netfd_t client_stfd)
|
|||
rtmp = new SrsRtmpServer(skt);
|
||||
refer = new SrsRefer();
|
||||
bandwidth = new SrsBandwidth();
|
||||
security = new SrsSecurity();
|
||||
duration = 0;
|
||||
kbps = new SrsKbps();
|
||||
kbps->set_io(skt, skt);
|
||||
|
@ -102,6 +104,7 @@ SrsRtmpConn::~SrsRtmpConn()
|
|||
srs_freep(skt);
|
||||
srs_freep(refer);
|
||||
srs_freep(bandwidth);
|
||||
srs_freep(security);
|
||||
srs_freep(kbps);
|
||||
}
|
||||
|
||||
|
@ -360,6 +363,13 @@ int SrsRtmpConn::stream_service_cycle()
|
|||
req->strip();
|
||||
srs_trace("client identified, type=%s, stream_name=%s, duration=%.2f",
|
||||
srs_client_type_string(type).c_str(), req->stream.c_str(), req->duration);
|
||||
|
||||
// security check
|
||||
if ((ret = security->check(type, ip, req)) != ERROR_SUCCESS) {
|
||||
srs_error("security check failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_info("security check ok");
|
||||
|
||||
// client is identified, set the timeout to service timeout.
|
||||
rtmp->set_recv_timeout(SRS_CONSTS_RTMP_RECV_TIMEOUT_US);
|
||||
|
|
|
@ -51,6 +51,7 @@ class SrsRtmpClient;
|
|||
class SrsSharedPtrMessage;
|
||||
class SrsQueueRecvThread;
|
||||
class SrsPublishRecvThread;
|
||||
class SrsSecurity;
|
||||
|
||||
/**
|
||||
* the client provides the main logic control for RTMP clients.
|
||||
|
@ -66,6 +67,7 @@ private:
|
|||
SrsRtmpServer* rtmp;
|
||||
SrsRefer* refer;
|
||||
SrsBandwidth* bandwidth;
|
||||
SrsSecurity* security;
|
||||
// elapse duration in ms
|
||||
// for live play duration, for instance, rtmpdump to record.
|
||||
// @see https://github.com/winlinvip/simple-rtmp-server/issues/47
|
||||
|
|
153
trunk/src/app/srs_app_security.cpp
Normal file
153
trunk/src/app/srs_app_security.cpp
Normal file
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2015 winlin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <srs_app_security.hpp>
|
||||
|
||||
#include <srs_kernel_error.hpp>
|
||||
#include <srs_app_config.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
SrsSecurity::SrsSecurity()
|
||||
{
|
||||
}
|
||||
|
||||
SrsSecurity::~SrsSecurity()
|
||||
{
|
||||
}
|
||||
|
||||
int SrsSecurity::check(SrsRtmpConnType type, string ip, SrsRequest* req)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
// allow all if security disabled.
|
||||
if (!_srs_config->get_security_enabled(req->vhost)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// default to deny all when security enabled.
|
||||
ret = ERROR_SYSTEM_SECURITY;
|
||||
|
||||
// rules to apply
|
||||
SrsConfDirective* rules = _srs_config->get_security_rules(req->vhost);
|
||||
if (!rules) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// allow if matches allow strategy.
|
||||
if (allow_check(rules, type, ip, req) == ERROR_SYSTEM_SECURITY_ALLOW) {
|
||||
ret = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// deny if matches deny strategy.
|
||||
if (deny_check(rules, type, ip, req) == ERROR_SYSTEM_SECURITY_DENY) {
|
||||
ret = ERROR_SYSTEM_SECURITY_DENY;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsSecurity::allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip, SrsRequest* req)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
for (int i = 0; i < (int)rules->directives.size(); i++) {
|
||||
SrsConfDirective* rule = rules->at(i);
|
||||
|
||||
if (rule->name != "allow") {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case SrsRtmpConnPlay:
|
||||
if (rule->arg0() != "play") {
|
||||
break;
|
||||
}
|
||||
if (rule->arg1() == "all" || rule->arg1() == ip) {
|
||||
ret = ERROR_SYSTEM_SECURITY_ALLOW;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SrsRtmpConnFMLEPublish:
|
||||
case SrsRtmpConnFlashPublish:
|
||||
if (rule->arg0() != "publish") {
|
||||
break;
|
||||
}
|
||||
if (rule->arg1() == "all" || rule->arg1() == ip) {
|
||||
ret = ERROR_SYSTEM_SECURITY_ALLOW;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// when matched, donot search more.
|
||||
if (ret == ERROR_SYSTEM_SECURITY_ALLOW) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsSecurity::deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip, SrsRequest* req)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
for (int i = 0; i < (int)rules->directives.size(); i++) {
|
||||
SrsConfDirective* rule = rules->at(i);
|
||||
|
||||
if (rule->name != "deny") {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case SrsRtmpConnPlay:
|
||||
if (rule->arg0() != "play") {
|
||||
break;
|
||||
}
|
||||
if (rule->arg1() == "all" || rule->arg1() == ip) {
|
||||
ret = ERROR_SYSTEM_SECURITY_DENY;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SrsRtmpConnFMLEPublish:
|
||||
case SrsRtmpConnFlashPublish:
|
||||
if (rule->arg0() != "publish") {
|
||||
break;
|
||||
}
|
||||
if (rule->arg1() == "all" || rule->arg1() == ip) {
|
||||
ret = ERROR_SYSTEM_SECURITY_DENY;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// when matched, donot search more.
|
||||
if (ret == ERROR_SYSTEM_SECURITY_DENY) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
70
trunk/src/app/srs_app_security.hpp
Normal file
70
trunk/src/app/srs_app_security.hpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2015 winlin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SRS_APP_SECURITY_HPP
|
||||
#define SRS_APP_SECURITY_HPP
|
||||
|
||||
/*
|
||||
#include <srs_app_security.hpp>
|
||||
*/
|
||||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <srs_protocol_rtmp.hpp>
|
||||
|
||||
class SrsConfDirective;
|
||||
|
||||
/**
|
||||
* the security apply on vhost.
|
||||
* @see https://github.com/winlinvip/simple-rtmp-server/issues/211
|
||||
*/
|
||||
class SrsSecurity
|
||||
{
|
||||
public:
|
||||
SrsSecurity();
|
||||
virtual ~SrsSecurity();
|
||||
public:
|
||||
/**
|
||||
* security check the client apply by vhost security strategy
|
||||
* @param type the client type, publish or play.
|
||||
* @param ip the ip address of client.
|
||||
* @param req the request object of client.
|
||||
*/
|
||||
virtual int check(SrsRtmpConnType type, std::string ip, SrsRequest* req);
|
||||
private:
|
||||
/**
|
||||
* security check the allow,
|
||||
* @return, if allowed, ERROR_SYSTEM_SECURITY_ALLOW.
|
||||
*/
|
||||
virtual int allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip, SrsRequest* req);
|
||||
/**
|
||||
* security check the deny,
|
||||
* @return, if allowed, ERROR_SYSTEM_SECURITY_DENY.
|
||||
*/
|
||||
virtual int deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip, SrsRequest* req);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
// current release version
|
||||
#define VERSION_MAJOR 2
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 85
|
||||
#define VERSION_REVISION 86
|
||||
// server info.
|
||||
#define RTMP_SIG_SRS_KEY "SRS"
|
||||
#define RTMP_SIG_SRS_ROLE "origin/edge server"
|
||||
|
|
|
@ -90,6 +90,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define ERROR_SYSTEM_FILE_SEEK 1049
|
||||
#define ERROR_SYSTEM_IO_INVALID 1050
|
||||
#define ERROR_ST_EXCEED_THREADS 1051
|
||||
#define ERROR_SYSTEM_SECURITY 1052
|
||||
#define ERROR_SYSTEM_SECURITY_DENY 1053
|
||||
#define ERROR_SYSTEM_SECURITY_ALLOW 1054
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// RTMP protocol error.
|
||||
|
|
|
@ -104,6 +104,8 @@ file
|
|||
..\app\srs_app_rtmp_conn.cpp,
|
||||
..\app\srs_app_pithy_print.hpp,
|
||||
..\app\srs_app_pithy_print.cpp,
|
||||
..\app\srs_app_security.hpp,
|
||||
..\app\srs_app_security.cpp,
|
||||
..\app\srs_app_server.hpp,
|
||||
..\app\srs_app_server.cpp,
|
||||
..\app\srs_app_st.hpp,
|
||||
|
|
Loading…
Reference in a new issue