Fix proxy redirect
Fix proxy redirect considering variables available on proxy side.
thiagoftsm committed
Aug 19, 2020 at 16:44 UTC
41168009c6e20ad4c925c42adc8cf788e049fd5f
4 files changed
+20
-5
libnetdata/socket/security.h
+2
-1
@@ -10,6 +10,7 @@
10
# define NETDATA_SSL_FORCE 32 //We only accepts HTTPS request
11
# define NETDATA_SSL_INVALID_CERTIFICATE 64 //Accepts invalid certificate
12
# define NETDATA_SSL_VALID_CERTIFICATE 128 //Accepts invalid certificate
13
+# define NETDATA_SSL_PROXY_HTTPS 256 //Proxy is using HTTPS
14
15
#define NETDATA_SSL_CONTEXT_SERVER 0
16
#define NETDATA_SSL_CONTEXT_STREAMING 1
@@ -30,7 +31,7 @@
31
32
struct netdata_ssl{
33
SSL *conn; //SSL connection
33
- int flags; //The flags for SSL connection
34
+ uint32_t flags; //The flags for SSL connection
35
};
36
37
extern SSL_CTX *netdata_opentsdb_ctx;
web/server/web_client.c
+15
-2
@@ -733,7 +733,8 @@ const char *web_response_code_to_string(int code) {
733
}
734
735
static inline char *http_header_parse(struct web_client *w, char *s, int parse_useragent) {
736
- static uint32_t hash_origin = 0, hash_connection = 0, hash_donottrack = 0, hash_useragent = 0, hash_authorization = 0, hash_host = 0;
736
+ static uint32_t hash_origin = 0, hash_connection = 0, hash_donottrack = 0, hash_useragent = 0,
737
+ hash_authorization = 0, hash_host = 0, hash_forwarded_proto = 0, hash_forwarded_host = 0;
738
#ifdef NETDATA_WITH_ZLIB
739
static uint32_t hash_accept_encoding = 0;
740
#endif
@@ -748,6 +749,8 @@ static inline char *http_header_parse(struct web_client *w, char *s, int parse_u
749
hash_useragent = simple_uhash("User-Agent");
750
hash_authorization = simple_uhash("X-Auth-Token");
751
hash_host = simple_uhash("Host");
752
+ hash_forwarded_proto = simple_uhash("X-Forwarded-Proto");
753
+ hash_forwarded_host = simple_uhash("X-Forwarded-Host");
754
}
755
756
char *e = s;
@@ -809,6 +812,13 @@ static inline char *http_header_parse(struct web_client *w, char *s, int parse_u
812
}
813
}
814
#endif /* NETDATA_WITH_ZLIB */
815
+ else if(hash == hash_forwarded_proto && !strcasecmp(s, "X-Forwarded-Proto")) {
816
+ if(strcasestr(v, "https"))
817
+ w->ssl.flags |= NETDATA_SSL_PROXY_HTTPS;
818
+ }
819
+ else if(hash == hash_forwarded_host && !strcasecmp(s, "X-Forwarded-Host")){
820
+ strncpyz(w->forwarded_host, v, ((size_t)(ve - v) < sizeof(w->server_host)-1 ? (size_t)(ve - v) : sizeof(w->server_host)-1));
821
+ }
822
823
*e = ':';
824
*ve = '\r';
@@ -1345,7 +1355,10 @@ static inline int web_client_switch_host(RRDHOST *host, struct web_client *w, ch
1355
1356
if(!url) { //no delim found
1357
debug(D_WEB_CLIENT, "%llu: URL doesn't end with / generating redirect.", w->id);
1348
- buffer_sprintf(w->response.header, "Location: http://%s%s/\r\n", w->server_host, w->last_url);
1358
+ char *protocol, *url_host;
1359
+ protocol = ((w->ssl.conn && !w->ssl.flags) || w->ssl.flags & NETDATA_SSL_PROXY_HTTPS) ? "https" : "http";
1360
+ url_host = (!w->forwarded_host[0])?w->server_host:w->forwarded_host;
1361
+ buffer_sprintf(w->response.header, "Location: %s://%s%s/\r\n", protocol, url_host, w->last_url);
1362
buffer_strcat(w->response.data, "Permanent redirect");
1363
return HTTP_RESP_REDIR_PERM;
1364
}
web/server/web_client.h
+1
@@ -155,6 +155,7 @@ struct web_client {
155
char client_port[NI_MAXSERV];
156
char server_host[NI_MAXHOST];
157
char client_host[NI_MAXHOST];
158
+ char forwarded_host[NI_MAXHOST]; //Used with proxy
159
160
char decoded_url[NETDATA_WEB_REQUEST_URL_SIZE + 1]; // we decode the URL in this buffer
161
char decoded_query_string[NETDATA_WEB_REQUEST_URL_SIZE + 1]; // we decode the Query String in this buffer
web/server/web_client_cache.c
+2
-2
@@ -188,7 +188,7 @@ struct web_client *web_client_get_from_cache_or_allocate() {
188
#ifdef ENABLE_HTTPS
189
w->ssl.conn = ssl;
190
w->ssl.flags = NETDATA_SSL_START;
191
- debug(D_WEB_CLIENT_ACCESS,"Reusing SSL structure with (w->ssl = NULL, w->accepted = %d)",w->ssl.flags);
191
+ debug(D_WEB_CLIENT_ACCESS,"Reusing SSL structure with (w->ssl = NULL, w->accepted = %u)", w->ssl.flags);
192
#endif
193
}
194
else {
@@ -196,7 +196,7 @@ struct web_client *web_client_get_from_cache_or_allocate() {
196
w = web_client_alloc();
197
#ifdef ENABLE_HTTPS
198
w->ssl.flags = NETDATA_SSL_START;
199
- debug(D_WEB_CLIENT_ACCESS,"Starting SSL structure with (w->ssl = NULL, w->accepted = %d)",w->ssl.flags);
199
+ debug(D_WEB_CLIENT_ACCESS,"Starting SSL structure with (w->ssl = NULL, w->accepted = %u)", w->ssl.flags);
200
#endif
201
web_clients_cache.allocated++;
202
}