master
c 151 lines 5.67 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #define WEB_SERVER_INTERNALS 1
4 #include "web_server.h"
5
6 WEB_SERVER_MODE web_server_mode = WEB_SERVER_MODE_STATIC_THREADED;
7
8 // --------------------------------------------------------------------------------------
9
10 WEB_SERVER_MODE web_server_mode_id(const char *mode) {
11 if(!strcmp(mode, "none"))
12 return WEB_SERVER_MODE_NONE;
13 else
14 return WEB_SERVER_MODE_STATIC_THREADED;
15
16 }
17
18 const char *web_server_mode_name(WEB_SERVER_MODE id) {
19 switch(id) {
20 case WEB_SERVER_MODE_NONE:
21 return "none";
22 default:
23 case WEB_SERVER_MODE_STATIC_THREADED:
24 return "static-threaded";
25 }
26 }
27
28 // --------------------------------------------------------------------------------------
29 // API sockets
30
31 LISTEN_SOCKETS api_sockets = {
32 .config = &netdata_config,
33 .config_section = CONFIG_SECTION_WEB,
34 .default_bind_to = "*",
35 .default_port = API_LISTEN_PORT,
36 .backlog = API_LISTEN_BACKLOG
37 };
38
39 void debug_sockets() {
40 BUFFER *wb = buffer_create(256 * sizeof(char), NULL);
41 int i;
42
43 for(i = 0 ; i < (int)api_sockets.opened ; i++) {
44 buffer_strcat(wb, (api_sockets.fds_acl_flags[i] & HTTP_ACL_NOCHECK) ? "NONE " : "");
45 buffer_strcat(wb, (api_sockets.fds_acl_flags[i] & HTTP_ACL_DASHBOARD) ? "dashboard " : "");
46 buffer_strcat(wb, (api_sockets.fds_acl_flags[i] & HTTP_ACL_REGISTRY) ? "registry " : "");
47 buffer_strcat(wb, (api_sockets.fds_acl_flags[i] & HTTP_ACL_BADGES) ? "badges " : "");
48 buffer_strcat(wb, (api_sockets.fds_acl_flags[i] & HTTP_ACL_MANAGEMENT) ? "management " : "");
49 buffer_strcat(wb, (api_sockets.fds_acl_flags[i] & HTTP_ACL_STREAMING) ? "streaming " : "");
50 buffer_strcat(wb, (api_sockets.fds_acl_flags[i] & HTTP_ACL_NETDATACONF) ? "netdata.conf " : "");
51 netdata_log_debug(D_WEB_CLIENT, "Socket fd %d name '%s' acl_flags: %s",
52 i,
53 api_sockets.fds_names[i],
54 buffer_tostring(wb));
55 buffer_reset(wb);
56 }
57 buffer_free(wb);
58 }
59
60 void web_server_listen_sockets_setup(void) {
61 errno_clear();
62
63 int socks = listen_sockets_setup(&api_sockets);
64 if(!socks) {
65 exit_initiated_add(EXIT_REASON_ALREADY_RUNNING);
66 daemon_status_file_update_status(DAEMON_STATUS_NONE);
67 fatal("Cannot setup listen port(s). Is Netdata already running?");
68 }
69
70 if(unlikely(debug_flags & D_WEB_CLIENT))
71 debug_sockets();
72
73 websocket_initialize();
74 }
75
76
77 // --------------------------------------------------------------------------------------
78 // access lists
79
80 SIMPLE_PATTERN *web_allow_connections_from = NULL;
81 int web_allow_connections_dns;
82
83 // WEB_CLIENT_ACL
84 SIMPLE_PATTERN *web_allow_dashboard_from = NULL;
85 int web_allow_dashboard_dns;
86 SIMPLE_PATTERN *web_allow_registry_from = NULL;
87 int web_allow_registry_dns;
88 SIMPLE_PATTERN *web_allow_badges_from = NULL;
89 int web_allow_badges_dns;
90 SIMPLE_PATTERN *web_allow_mgmt_from = NULL;
91 int web_allow_mgmt_dns;
92 SIMPLE_PATTERN *web_allow_streaming_from = NULL;
93 int web_allow_streaming_dns;
94 SIMPLE_PATTERN *web_allow_netdataconf_from = NULL;
95 int web_allow_netdataconf_dns;
96
97 void web_client_update_acl_matches(struct web_client *w) {
98 w->acl = HTTP_ACL_TRANSPORTS;
99
100 if(!(w->port_acl & HTTP_ACL_TRANSPORTS_WITHOUT_CLIENT_IP_VALIDATION)) {
101 if (!web_allow_dashboard_from ||
102 connection_allowed(w->fd, w->user_auth.client_ip, w->client_host, sizeof(w->client_host),
103 web_allow_dashboard_from, "dashboard", web_allow_dashboard_dns))
104 w->acl |= HTTP_ACL_DASHBOARD;
105
106 if (!web_allow_registry_from ||
107 connection_allowed(w->fd, w->user_auth.client_ip, w->client_host, sizeof(w->client_host),
108 web_allow_registry_from, "registry", web_allow_registry_dns))
109 w->acl |= HTTP_ACL_REGISTRY;
110
111 if (!web_allow_badges_from ||
112 connection_allowed(w->fd, w->user_auth.client_ip, w->client_host, sizeof(w->client_host),
113 web_allow_badges_from, "badges", web_allow_badges_dns))
114 w->acl |= HTTP_ACL_BADGES;
115
116 if (!web_allow_mgmt_from ||
117 connection_allowed(w->fd, w->user_auth.client_ip, w->client_host, sizeof(w->client_host),
118 web_allow_mgmt_from, "management", web_allow_mgmt_dns))
119 w->acl |= HTTP_ACL_MANAGEMENT;
120
121 if (!web_allow_streaming_from ||
122 connection_allowed(w->fd, w->user_auth.client_ip, w->client_host, sizeof(w->client_host),
123 web_allow_streaming_from, "streaming", web_allow_streaming_dns))
124 w->acl |= HTTP_ACL_STREAMING;
125
126 if (!web_allow_netdataconf_from ||
127 connection_allowed(w->fd, w->user_auth.client_ip, w->client_host, sizeof(w->client_host),
128 web_allow_netdataconf_from, "netdata.conf", web_allow_netdataconf_dns))
129 w->acl |= HTTP_ACL_NETDATACONF;
130 }
131
132 w->acl &= w->port_acl;
133 }
134
135
136 // --------------------------------------------------------------------------------------
137
138 void web_server_log_connection(struct web_client *w, const char *msg) {
139 ND_LOG_STACK lgs[] = {
140 ND_LOG_FIELD_U64(NDF_CONNECTION_ID, w->id),
141 ND_LOG_FIELD_TXT(NDF_SRC_TRANSPORT, SSL_connection(&w->ssl) ? "https" : "http"),
142 ND_LOG_FIELD_TXT(NDF_SRC_IP, w->user_auth.client_ip),
143 ND_LOG_FIELD_TXT(NDF_SRC_PORT, w->client_port),
144 ND_LOG_FIELD_TXT(NDF_SRC_FORWARDED_HOST, w->forwarded_host),
145 ND_LOG_FIELD_TXT(NDF_SRC_FORWARDED_FOR, w->user_auth.forwarded_for),
146 ND_LOG_FIELD_END(),
147 };
148 ND_LOG_STACK_PUSH(lgs);
149
150 nd_log(NDLS_ACCESS, NDLP_DEBUG, "[%s]:%s %s", w->user_auth.client_ip, w->client_port, msg);
151 }