@cryptotaxi247 / netdata-1 / commits / 06884d650

add web API port access list; #2636

Costa Tsaousis (ktsaou) committed Sep 17, 2017 at 14:24 UTC 06884d65023130a49b3103f66e4a465402dcb0bd
6 files changed +31 -6
src/main.c
+2
@@ -83,6 +83,8 @@ 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 allow from", "127.* ::1 *"), SIMPLE_PATTERN_EXACT);
87 +
88 #ifdef NETDATA_WITH_ZLIB
89 web_enable_gzip = config_get_boolean(CONFIG_SECTION_WEB, "enable gzip compression", web_enable_gzip);
90
src/socket.c
+18 -3
@@ -857,7 +857,7 @@ int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags) {
857 // --------------------------------------------------------------------------------------------------------------------
858 // accept_socket() - accept a socket and store client IP and port
859
860 -int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *client_port, size_t portsize) {
860 +int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *client_port, size_t portsize, SIMPLE_PATTERN *access_list) {
861 struct sockaddr_storage sadr;
862 socklen_t addrlen = sizeof(sadr);
863
@@ -881,7 +881,8 @@ int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *clien
881 if (strncmp(client_ip, "::ffff:", 7) == 0) {
882 memmove(client_ip, &client_ip[7], strlen(&client_ip[7]) + 1);
883 debug(D_LISTENER, "New IPv4 web client from %s port %s on socket %d.", client_ip, client_port, fd);
884 - } else
884 + }
885 + else
886 debug(D_LISTENER, "New IPv6 web client from %s port %s on socket %d.", client_ip, client_port, fd);
887 break;
888
@@ -889,6 +890,17 @@ int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *clien
890 debug(D_LISTENER, "New UNKNOWN web client from %s port %s on socket %d.", client_ip, client_port, fd);
891 break;
892 }
893 +
894 + if(access_list) {
895 + if(unlikely(!simple_pattern_matches(access_list, client_ip))) {
896 + errno = 0;
897 + debug(D_LISTENER, "Permission denied for client '%s', port '%s'", client_ip, client_port);
898 + error("DENIED ACCESS to client '%s'", client_ip);
899 + close(nfd);
900 + nfd = -1;
901 + errno = EPERM;
902 + }
903 + }
904 }
905 #ifdef HAVE_ACCEPT4
906 else if(errno == ENOSYS)
@@ -1104,6 +1116,7 @@ void poll_events(LISTEN_SOCKETS *sockets
1116 , void (*del_callback)(int fd, void *data)
1117 , int (*rcv_callback)(int fd, int socktype, void *data, short int *events)
1118 , int (*snd_callback)(int fd, int socktype, void *data, short int *events)
1119 + , SIMPLE_PATTERN *access_list
1120 , void *data
1121 ) {
1122 int retval;
@@ -1182,7 +1195,7 @@ void poll_events(LISTEN_SOCKETS *sockets
1195 char client_port[NI_MAXSERV + 1];
1196
1197 debug(D_POLLFD, "POLLFD: LISTENER: calling accept4() slot %zu (fd %d)", i, fd);
1185 - nfd = accept_socket(fd, SOCK_NONBLOCK, client_ip, NI_MAXHOST + 1, client_port, NI_MAXSERV + 1);
1198 + nfd = accept_socket(fd, SOCK_NONBLOCK, client_ip, NI_MAXHOST + 1, client_port, NI_MAXSERV + 1, access_list);
1199 if (nfd < 0) {
1200 // accept failed
1201
@@ -1212,6 +1225,8 @@ void poll_events(LISTEN_SOCKETS *sockets
1225
1226 debug(D_POLLFD, "POLLFD: LISTENER: reading data from UDP slot %zu (fd %d)", i, fd);
1227
1228 + // FIXME: access_list is not applied to UDP
1229 +
1230 p.rcv_callback(fd, pi->socktype, pi->data, &pf->events);
1231 break;
1232 }
src/socket.h
+2 -1
@@ -35,7 +35,7 @@ extern int sock_setreuse_port(int fd, int reuse);
35 extern int sock_enlarge_in(int fd);
36 extern int sock_enlarge_out(int fd);
37
38 -extern int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *client_port, size_t portsize);
38 +extern int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *client_port, size_t portsize, SIMPLE_PATTERN *access_list);
39
40 #ifndef HAVE_ACCEPT4
41 extern int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags);
@@ -56,6 +56,7 @@ extern void poll_events(LISTEN_SOCKETS *sockets
56 , void (*del_callback)(int fd, void *data)
57 , int (*rcv_callback)(int fd, int socktype, void *data, short int *events)
58 , int (*snd_callback)(int fd, int socktype, void *data, short int *events)
59 + , SIMPLE_PATTERN *access_list
60 , void *data
61 );
62
src/statsd.c
+1
@@ -912,6 +912,7 @@ void *statsd_collector_thread(void *ptr) {
912 , statsd_del_callback
913 , statsd_rcv_callback
914 , statsd_snd_callback
915 + , NULL
916 , (void *)d
917 );
918
src/web_client.c
+7 -2
@@ -8,6 +8,8 @@ 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;
12 +
13 #ifdef NETDATA_WITH_ZLIB
14 int web_enable_gzip = 1, web_gzip_level = 3, web_gzip_strategy = Z_DEFAULT_STRATEGY;
15 #endif /* NETDATA_WITH_ZLIB */
@@ -58,9 +60,12 @@ struct web_client *web_client_create(int listener) {
60 w->mode = WEB_CLIENT_MODE_NORMAL;
61
62 {
61 - w->ifd = accept_socket(listener, SOCK_NONBLOCK, w->client_ip, sizeof(w->client_ip), w->client_port, sizeof(w->client_port));
63 + 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);
64 if (w->ifd == -1) {
63 - error("%llu: Cannot accept new incoming connection.", w->id);
65 +
66 + if(errno != EPERM)
67 + error("%llu: Failed to accept new incoming connection.", w->id);
68 +
69 freez(w);
70 return NULL;
71 }
src/web_client.h
+1
@@ -142,6 +142,7 @@ struct web_client {
142 };
143
144 extern struct web_client *web_clients;
145 +extern SIMPLE_PATTERN *web_client_access_list;
146
147 extern uid_t web_files_uid(void);
148 extern uid_t web_files_gid(void);