| 1 | # Running Netdata behind HAProxy |
| 2 | |
| 3 | > HAProxy is a free, very fast and reliable solution offering high availability, load balancing, and proxying for TCP and HTTP-based applications. It is particularly suited for very high traffic websites |
| 4 | > and powers quite a number of the world's most visited ones. |
| 5 | |
| 6 | If Netdata is running on a host running HAProxy, rather than connecting to Netdata from a port number, a domain name can |
| 7 | be pointed at HAProxy, and HAProxy can redirect connections to the Netdata port. This can make it possible to connect to |
| 8 | Netdata at `https://example.com` or `https://example.com/netdata/`, which is a much nicer experience then |
| 9 | `http://example.com:19999`. |
| 10 | |
| 11 | To proxy requests from [HAProxy](https://github.com/haproxy/haproxy) to Netdata, |
| 12 | the following configuration can be used: |
| 13 | |
| 14 | ## Default Configuration |
| 15 | |
| 16 | For all examples, set the mode to `http` |
| 17 | |
| 18 | ```text |
| 19 | defaults |
| 20 | mode http |
| 21 | ``` |
| 22 | |
| 23 | ## Simple Configuration |
| 24 | |
| 25 | A simple example where the base URL, say `http://example.com`, is used with no subpath: |
| 26 | |
| 27 | ### Frontend |
| 28 | |
| 29 | Create a frontend to receive the request. |
| 30 | |
| 31 | ```text |
| 32 | frontend http_frontend |
| 33 | ## HTTP ipv4 and ipv6 on all ips ## |
| 34 | bind :::80 v4v6 |
| 35 | |
| 36 | default_backend netdata_backend |
| 37 | ``` |
| 38 | |
| 39 | ### Backend |
| 40 | |
| 41 | Create the Netdata backend which will send requests to port `19999`. |
| 42 | |
| 43 | ```text |
| 44 | backend netdata_backend |
| 45 | option forwardfor |
| 46 | server netdata_local 127.0.0.1:19999 |
| 47 | |
| 48 | http-request set-header Host %[src] |
| 49 | http-request set-header X-Forwarded-For %[src] |
| 50 | http-request set-header X-Forwarded-Port %[dst_port] |
| 51 | http-request set-header Connection "keep-alive" |
| 52 | ``` |
| 53 | |
| 54 | ## Configuration with subpath |
| 55 | |
| 56 | An example where the base URL is used with a subpath `/netdata/`: |
| 57 | |
| 58 | ### Frontend |
| 59 | |
| 60 | To use a subpath, create an ACL, which will set a variable based on the subpath. |
| 61 | |
| 62 | ```text |
| 63 | frontend http_frontend |
| 64 | ## HTTP ipv4 and ipv6 on all ips ## |
| 65 | bind :::80 v4v6 |
| 66 | |
| 67 | # URL begins with /netdata |
| 68 | acl is_netdata url_beg /netdata |
| 69 | |
| 70 | # if trailing slash is missing, redirect to /netdata/ |
| 71 | http-request redirect scheme https drop-query append-slash if is_netdata ! { path_beg /netdata/ } |
| 72 | |
| 73 | ## Backends ## |
| 74 | use_backend netdata_backend if is_netdata |
| 75 | |
| 76 | # Other requests go here (optional) |
| 77 | # put netdata_backend here if no others are used |
| 78 | default_backend www_backend |
| 79 | ``` |
| 80 | |
| 81 | ### Backend |
| 82 | |
| 83 | Same as simple example, except remove `/netdata/` with regex. |
| 84 | |
| 85 | ```text |
| 86 | backend netdata_backend |
| 87 | option forwardfor |
| 88 | server netdata_local 127.0.0.1:19999 |
| 89 | |
| 90 | http-request set-path %[path,regsub(^/netdata/,/)] |
| 91 | |
| 92 | http-request set-header Host %[src] |
| 93 | http-request set-header X-Forwarded-For %[src] |
| 94 | http-request set-header X-Forwarded-Port %[dst_port] |
| 95 | http-request set-header Connection "keep-alive" |
| 96 | ``` |
| 97 | |
| 98 | ## Using TLS communication |
| 99 | |
| 100 | TLS can be used by adding port `443` and a cert to the frontend. |
| 101 | This example will only use Netdata if host matches example.com (replace with your domain). |
| 102 | |
| 103 | ### Frontend |
| 104 | |
| 105 | This frontend uses a certificate list. |
| 106 | |
| 107 | ```text |
| 108 | frontend https_frontend |
| 109 | ## HTTP ## |
| 110 | bind :::80 v4v6 |
| 111 | # Redirect all HTTP traffic to HTTPS with 301 redirect |
| 112 | redirect scheme https code 301 if !{ ssl_fc } |
| 113 | |
| 114 | ## HTTPS ## |
| 115 | # Bind to all v4/v6 addresses, use a list of certs in file |
| 116 | bind :::443 v4v6 ssl crt-list /etc/letsencrypt/certslist.txt |
| 117 | |
| 118 | ## ACL ## |
| 119 | # Optionally check host for Netdata |
| 120 | acl is_example_host hdr_sub(host) -i example.com |
| 121 | |
| 122 | ## Backends ## |
| 123 | use_backend netdata_backend if is_example_host |
| 124 | # Other requests go here (optional) |
| 125 | default_backend www_backend |
| 126 | ``` |
| 127 | |
| 128 | In the cert list file place a mapping from a certificate file to the domain used: |
| 129 | |
| 130 | `/etc/letsencrypt/certslist.txt`: |
| 131 | |
| 132 | ```text |
| 133 | example.com /etc/letsencrypt/live/example.com/example.com.pem |
| 134 | ``` |
| 135 | |
| 136 | The file `/etc/letsencrypt/live/example.com/example.com.pem` should contain the key and |
| 137 | certificate (in that order) concatenated into a `.pem` file.: |
| 138 | |
| 139 | ```sh |
| 140 | cat /etc/letsencrypt/live/example.com/fullchain.pem \ |
| 141 | /etc/letsencrypt/live/example.com/privkey.pem > \ |
| 142 | /etc/letsencrypt/live/example.com/example.com.pem |
| 143 | ``` |
| 144 | |
| 145 | ### Backend |
| 146 | |
| 147 | Same as simple, except set protocol `https`. |
| 148 | |
| 149 | ```text |
| 150 | backend netdata_backend |
| 151 | option forwardfor |
| 152 | server netdata_local 127.0.0.1:19999 |
| 153 | |
| 154 | http-request add-header X-Forwarded-Proto https |
| 155 | http-request set-header Host %[src] |
| 156 | http-request set-header X-Forwarded-For %[src] |
| 157 | http-request set-header X-Forwarded-Port %[dst_port] |
| 158 | http-request set-header Connection "keep-alive" |
| 159 | ``` |
| 160 | |
| 161 | ## Enable authentication |
| 162 | |
| 163 | :::tip Simpler Alternative |
| 164 | |
| 165 | If you use Netdata Cloud, [Bearer Token Protection](/docs/netdata-agent/configuration/secure-your-netdata-agent-with-bearer-token.md) provides authentication with a single setting - no HAProxy userlist configuration needed. |
| 166 | |
| 167 | ::: |
| 168 | |
| 169 | To use basic HTTP Authentication, create an authentication list: |
| 170 | |
| 171 | ```text |
| 172 | # HTTP Auth |
| 173 | userlist basic-auth-list |
| 174 | group is-admin |
| 175 | # Plaintext password |
| 176 | user admin password YOUR_PASSWORD groups is-admin |
| 177 | ``` |
| 178 | |
| 179 | You can create a hashed password using the `mkpassword` utility. |
| 180 | |
| 181 | ```sh |
| 182 | printf "YOUR_PASSWORD" | mkpasswd --stdin --method=sha-256 |
| 183 | $5$l7Gk0VPIpKO$f5iEcxvjfdF11khw.utzSKqP7W.0oq8wX9nJwPLwzy1 |
| 184 | ``` |
| 185 | |
| 186 | Replace `YOUR_PASSWORD` with hash: |
| 187 | |
| 188 | ```text |
| 189 | user admin password $5$l7Gk0VPIpKO$f5iEcxvjfdF11khw.utzSKqP7W.0oq8wX9nJwPLwzy1 groups is-admin |
| 190 | ``` |
| 191 | |
| 192 | Now add at the top of the backend: |
| 193 | |
| 194 | ```text |
| 195 | acl devops-auth http_auth_group(basic-auth-list) is-admin |
| 196 | http-request auth realm netdata_local unless devops-auth |
| 197 | ``` |
| 198 | |
| 199 | ## Full Example |
| 200 | |
| 201 | Full example configuration with HTTP auth over TLS with subpath: |
| 202 | |
| 203 | ```text |
| 204 | global |
| 205 | maxconn 20000 |
| 206 | |
| 207 | log /dev/log local0 |
| 208 | log /dev/log local1 notice |
| 209 | user haproxy |
| 210 | group haproxy |
| 211 | pidfile /run/haproxy.pid |
| 212 | |
| 213 | stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners |
| 214 | stats timeout 30s |
| 215 | daemon |
| 216 | |
| 217 | tune.ssl.default-dh-param 4096 # Max size of DHE key |
| 218 | |
| 219 | # Default ciphers to use on SSL-enabled listening sockets. |
| 220 | ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS |
| 221 | ssl-default-bind-options no-sslv3 |
| 222 | |
| 223 | defaults |
| 224 | log global |
| 225 | mode http |
| 226 | option httplog |
| 227 | option dontlognull |
| 228 | timeout connect 5000 |
| 229 | timeout client 50000 |
| 230 | timeout server 50000 |
| 231 | errorfile 400 /etc/haproxy/errors/400.http |
| 232 | errorfile 403 /etc/haproxy/errors/403.http |
| 233 | errorfile 408 /etc/haproxy/errors/408.http |
| 234 | errorfile 500 /etc/haproxy/errors/500.http |
| 235 | errorfile 502 /etc/haproxy/errors/502.http |
| 236 | errorfile 503 /etc/haproxy/errors/503.http |
| 237 | errorfile 504 /etc/haproxy/errors/504.http |
| 238 | |
| 239 | frontend https_frontend |
| 240 | ## HTTP ## |
| 241 | bind :::80 v4v6 |
| 242 | # Redirect all HTTP traffic to HTTPS with 301 redirect |
| 243 | redirect scheme https code 301 if !{ ssl_fc } |
| 244 | |
| 245 | ## HTTPS ## |
| 246 | # Bind to all v4/v6 addresses, use a list of certs in file |
| 247 | bind :::443 v4v6 ssl crt-list /etc/letsencrypt/certslist.txt |
| 248 | |
| 249 | ## ACL ## |
| 250 | # Optionally check host for Netdata |
| 251 | acl is_example_host hdr_sub(host) -i example.com |
| 252 | acl is_netdata url_beg /netdata |
| 253 | |
| 254 | http-request redirect scheme https drop-query append-slash if is_netdata ! { path_beg /netdata/ } |
| 255 | |
| 256 | ## Backends ## |
| 257 | use_backend netdata_backend if is_example_host is_netdata |
| 258 | default_backend www_backend |
| 259 | |
| 260 | # HTTP Auth |
| 261 | userlist basic-auth-list |
| 262 | group is-admin |
| 263 | # Hashed password |
| 264 | user admin password $5$l7Gk0VPIpKO$f5iEcxvjfdF11khw.utzSKqP7W.0oq8wX9nJwPLwzy1 groups is-admin |
| 265 | |
| 266 | ## Default server(s) (optional)## |
| 267 | backend www_backend |
| 268 | mode http |
| 269 | balance roundrobin |
| 270 | timeout connect 5s |
| 271 | timeout server 30s |
| 272 | timeout queue 30s |
| 273 | |
| 274 | http-request add-header 'X-Forwarded-Proto: https' |
| 275 | server other_server 111.111.111.111:80 check |
| 276 | |
| 277 | backend netdata_backend |
| 278 | acl devops-auth http_auth_group(basic-auth-list) is-admin |
| 279 | http-request auth realm netdata_local unless devops-auth |
| 280 | |
| 281 | option forwardfor |
| 282 | server netdata_local 127.0.0.1:19999 |
| 283 | |
| 284 | http-request set-path %[path,regsub(^/netdata/,/)] |
| 285 | |
| 286 | http-request add-header X-Forwarded-Proto https |
| 287 | http-request set-header Host %[src] |
| 288 | http-request set-header X-Forwarded-For %[src] |
| 289 | http-request set-header X-Forwarded-Port %[dst_port] |
| 290 | http-request set-header Connection "keep-alive" |
| 291 | ``` |