added more access control lists; #2636
Costa Tsaousis (ktsaou) committed
Sep 18, 2017 at 00:29 UTC
52331eb4ab5ccc1239edb4398ed02e1a8ae4cc00
4 files changed
+63
-33
src/main.c
+4
-1
@@ -83,7 +83,10 @@ void web_server_config_options(void) {
83
web_x_frame_options = config_get(CONFIG_SECTION_WEB, "x-frame-options response header", "");
84
if(!*web_x_frame_options) web_x_frame_options = NULL;
85
86
- web_client_access_list = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "global API allow from", "127.* ::1 *"), SIMPLE_PATTERN_EXACT);
86
+ web_allow_connections_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow connections from", "127.* ::1 *"), SIMPLE_PATTERN_EXACT);
87
+ web_allow_badges_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow badges from", "*"), SIMPLE_PATTERN_EXACT);
88
+ web_allow_registry_from = simple_pattern_create(config_get(CONFIG_SECTION_REGISTRY, "allow from", "*"), SIMPLE_PATTERN_EXACT);
89
+ web_allow_streaming_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow streaming from", "*"), SIMPLE_PATTERN_EXACT);
90
91
#ifdef NETDATA_WITH_ZLIB
92
web_enable_gzip = config_get_boolean(CONFIG_SECTION_WEB, "enable gzip compression", web_enable_gzip);
src/web_api_v1.c
+35
-29
@@ -298,6 +298,9 @@ inline int web_client_api_request_v1_chart(RRDHOST *host, struct web_client *w,
298
}
299
300
int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *url) {
301
+ if(unlikely(web_allow_badges_from && !simple_pattern_matches(web_allow_badges_from, w->client_ip)))
302
+ return web_client_permission_denied(w);
303
+
304
int ret = 400;
305
buffer_flush(w->response.data);
306
@@ -816,55 +819,58 @@ inline int web_client_api_request_v1_registry(RRDHOST *host, struct web_client *
819
#endif /* NETDATA_INTERNAL_CHECKS */
820
}
821
819
- if(respect_web_browser_do_not_track_policy && web_client_has_donottrack(w)) {
822
+ if(unlikely(respect_web_browser_do_not_track_policy && web_client_has_donottrack(w))) {
823
buffer_flush(w->response.data);
824
buffer_sprintf(w->response.data, "Your web browser is sending 'DNT: 1' (Do Not Track). The registry requires persistent cookies on your browser to work.");
825
return 400;
826
}
827
825
- if(action == 'A' && (!machine_guid || !machine_url || !url_name)) {
826
- error("Invalid registry request - access requires these parameters: machine ('%s'), url ('%s'), name ('%s')",
827
- machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", url_name?url_name:"UNSET");
828
- buffer_flush(w->response.data);
829
- buffer_strcat(w->response.data, "Invalid registry Access request.");
830
- return 400;
831
- }
832
- else if(action == 'D' && (!machine_guid || !machine_url || !delete_url)) {
833
- error("Invalid registry request - delete requires these parameters: machine ('%s'), url ('%s'), delete_url ('%s')",
834
- machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", delete_url?delete_url:"UNSET");
835
- buffer_flush(w->response.data);
836
- buffer_strcat(w->response.data, "Invalid registry Delete request.");
837
- return 400;
838
- }
839
- else if(action == 'S' && (!machine_guid || !machine_url || !search_machine_guid)) {
840
- error("Invalid registry request - search requires these parameters: machine ('%s'), url ('%s'), for ('%s')",
841
- machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", search_machine_guid?search_machine_guid:"UNSET");
842
- buffer_flush(w->response.data);
843
- buffer_strcat(w->response.data, "Invalid registry Search request.");
844
- return 400;
845
- }
846
- else if(action == 'W' && (!machine_guid || !machine_url || !to_person_guid)) {
847
- error("Invalid registry request - switching identity requires these parameters: machine ('%s'), url ('%s'), to ('%s')",
848
- machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", to_person_guid?to_person_guid:"UNSET");
849
- buffer_flush(w->response.data);
850
- buffer_strcat(w->response.data, "Invalid registry Switch request.");
851
- return 400;
852
- }
828
+ // for all calls except HELLO, we have to check the ACL
829
+ if(unlikely(action != 'H' && web_allow_registry_from && !simple_pattern_matches(web_allow_registry_from, w->client_ip)))
830
+ return web_client_permission_denied(w);
831
832
switch(action) {
833
case 'A':
834
+ if(unlikely(!machine_guid || !machine_url || !url_name)) {
835
+ error("Invalid registry request - access requires these parameters: machine ('%s'), url ('%s'), name ('%s')", machine_guid ? machine_guid : "UNSET", machine_url ? machine_url : "UNSET", url_name ? url_name : "UNSET");
836
+ buffer_flush(w->response.data);
837
+ buffer_strcat(w->response.data, "Invalid registry Access request.");
838
+ return 400;
839
+ }
840
+
841
web_client_enable_tracking_required(w);
842
return registry_request_access_json(host, w, person_guid, machine_guid, machine_url, url_name, now_realtime_sec());
843
844
case 'D':
845
+ if(unlikely(!machine_guid || !machine_url || !delete_url)) {
846
+ error("Invalid registry request - delete requires these parameters: machine ('%s'), url ('%s'), delete_url ('%s')", machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", delete_url?delete_url:"UNSET");
847
+ buffer_flush(w->response.data);
848
+ buffer_strcat(w->response.data, "Invalid registry Delete request.");
849
+ return 400;
850
+ }
851
+
852
web_client_enable_tracking_required(w);
853
return registry_request_delete_json(host, w, person_guid, machine_guid, machine_url, delete_url, now_realtime_sec());
854
855
case 'S':
856
+ if(unlikely(!machine_guid || !machine_url || !search_machine_guid)) {
857
+ error("Invalid registry request - search requires these parameters: machine ('%s'), url ('%s'), for ('%s')", machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", search_machine_guid?search_machine_guid:"UNSET");
858
+ buffer_flush(w->response.data);
859
+ buffer_strcat(w->response.data, "Invalid registry Search request.");
860
+ return 400;
861
+ }
862
+
863
web_client_enable_tracking_required(w);
864
return registry_request_search_json(host, w, person_guid, machine_guid, machine_url, search_machine_guid, now_realtime_sec());
865
866
case 'W':
867
+ if(unlikely(!machine_guid || !machine_url || !to_person_guid)) {
868
+ error("Invalid registry request - switching identity requires these parameters: machine ('%s'), url ('%s'), to ('%s')", machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", to_person_guid?to_person_guid:"UNSET");
869
+ buffer_flush(w->response.data);
870
+ buffer_strcat(w->response.data, "Invalid registry Switch request.");
871
+ return 400;
872
+ }
873
+
874
web_client_enable_tracking_required(w);
875
return registry_request_switch_json(host, w, person_guid, machine_guid, machine_url, to_person_guid, now_realtime_sec());
876
src/web_client.c
+18
-2
@@ -8,7 +8,10 @@ int web_client_timeout = DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS;
8
int respect_web_browser_do_not_track_policy = 0;
9
char *web_x_frame_options = NULL;
10
11
-SIMPLE_PATTERN *web_client_access_list = NULL;
11
+SIMPLE_PATTERN *web_allow_connections_from = NULL;
12
+SIMPLE_PATTERN *web_allow_registry_from = NULL;
13
+SIMPLE_PATTERN *web_allow_badges_from = NULL;
14
+SIMPLE_PATTERN *web_allow_streaming_from = NULL;
15
16
#ifdef NETDATA_WITH_ZLIB
17
int web_enable_gzip = 1, web_gzip_level = 3, web_gzip_strategy = Z_DEFAULT_STRATEGY;
@@ -52,6 +55,14 @@ static inline int web_client_uncrock_socket(struct web_client *w) {
55
return 0;
56
}
57
58
+inline int web_client_permission_denied(struct web_client *w) {
59
+ w->response.data->contenttype = CT_TEXT_PLAIN;
60
+ buffer_flush(w->response.data);
61
+ buffer_strcat(w->response.data, "You do not allowed to access this resource.");
62
+ w->response.code = 403;
63
+ return 403;
64
+}
65
+
66
static void log_connection(struct web_client *w, const char *msg) {
67
log_access("%llu: %d '[%s]:%s' '%s'", w->id, gettid(), w->client_ip, w->client_port, msg);
68
}
@@ -64,7 +75,7 @@ struct web_client *web_client_create(int listener) {
75
w->mode = WEB_CLIENT_MODE_NORMAL;
76
77
{
67
- w->ifd = accept_socket(listener, SOCK_NONBLOCK, w->client_ip, sizeof(w->client_ip), w->client_port, sizeof(w->client_port), web_client_access_list);
78
+ w->ifd = accept_socket(listener, SOCK_NONBLOCK, w->client_ip, sizeof(w->client_ip), w->client_port, sizeof(w->client_port), web_allow_connections_from);
79
80
if(unlikely(!*w->client_ip)) strcpy(w->client_ip, "-");
81
if(unlikely(!*w->client_port)) strcpy(w->client_port, "-");
@@ -1235,6 +1246,11 @@ void web_client_process_request(struct web_client *w) {
1246
case HTTP_VALIDATION_OK:
1247
switch(w->mode) {
1248
case WEB_CLIENT_MODE_STREAM:
1249
+ if(unlikely(web_allow_streaming_from && !simple_pattern_matches(web_allow_streaming_from, w->client_ip))) {
1250
+ web_client_permission_denied(w);
1251
+ return;
1252
+ }
1253
+
1254
w->response.code = rrdpush_receiver_thread_spawn(localhost, w, w->decoded_url);
1255
return;
1256
src/web_client.h
+6
-1
@@ -142,11 +142,16 @@ struct web_client {
142
};
143
144
extern struct web_client *web_clients;
145
-extern SIMPLE_PATTERN *web_client_access_list;
145
+extern SIMPLE_PATTERN *web_allow_connections_from;
146
+extern SIMPLE_PATTERN *web_allow_registry_from;
147
+extern SIMPLE_PATTERN *web_allow_badges_from;
148
+extern SIMPLE_PATTERN *web_allow_streaming_from;
149
150
extern uid_t web_files_uid(void);
151
extern uid_t web_files_gid(void);
152
153
+extern int web_client_permission_denied(struct web_client *w);
154
+
155
extern struct web_client *web_client_create(int listener);
156
extern struct web_client *web_client_free(struct web_client *w);
157
extern ssize_t web_client_send(struct web_client *w);