# Technical Documentation: fabiolb/fabio > ℹ️ **Provenance:** Hybrid Fusion: `fabiolb/fabio` (README + 10 In-Tree Chapters) · [CodeWiki Reference](https://codewiki.google/github.com/fabiolb/fabio) · Recency: Active (< 180 days) ## 1. Project Overview & Quickstart (fabiolb/fabio) --- #### Notes 1) From release 1.6.1 onward, the minimum golang version supported is 1.16. 2) From release 1.6.0 onward, metrics backend statsd is no longer supported. statsd_raw works similarly, though it actually resets counters appropriately. If you are using datadog, you should consider using the new dogstatsd backend, which has support for tags now. Graphite histogram functionality has changed slightly since switching to gokit framework, so something to be aware of. Prometheus functionality is now supported natively. 3) From release 1.5.15 onward, fabio changes the default GOGC from 800 back to the golang default of 100. Apparently this made some sense back in the golang 1.5 days, but with changes introduced with golang 1.12 and others, this is probably no longer a very good default. This is still configurable, as always, but the new default should make the most sense for most users. 4) From release 1.5.14, release hashes are signed with a new PGP key. See details [here](https://fabiolb.net/faq/verifying-releases/). 5) From release 1.5.14 onward, fabio binary releases are compiled with golang 1.15+. This means that the fabio will no longer validate upstream https certificates that do not have SAN extensions matching the server name. This may be a concern if fabio is communicating with https backends with misconfigured certificates. If this is a problem, you can specify `tlsskipverify=true` on the route. --- fabio is a fast, modern, zero-conf load balancing HTTP(S) and TCP router for deploying applications managed by [consul](https://consul.io/). Register your services in consul, provide a health check and fabio will start routing traffic to them. No configuration required. Deployment, upgrading and refactoring has never been easier. fabio is developed and maintained by The Fabio Authors. It powers some of the largest websites in Australia ([gumtree.com.au](http://www.gumtree.com.au)). It delivers 23.000 req/sec every day since Sep 2015 without problems. It integrates with [Consul](https://consul.io/), [Vault](https://vaultproject.io/), [Amazon ELB](https://aws.amazon.com/elasticloadbalancing), [Amazon API Gateway](https://aws.amazon.com/api-gateway/) and more. It supports ([Full feature list](https://fabiolb.net/feature/)) * [TLS termination with dynamic certificate stores](https://fabiolb.net/feature/certificate-stores/) * [Raw TCP proxy](https://fabiolb.net/feature/tcp-proxy/) * [TCP+SNI proxy for full end-to-end TLS](https://fabiolb.net/feature/tcp-sni-proxy/) without decryption * [HTTPS+TCP+SNI proxy for TCP+SNI with HTTPS fallback](https://fabiolb.net/feature/https-tcp-sni-proxy/) * [TCP dynamic proxy](https://fabiolb.net/feature/tcp-dynamic-proxy/) * [HTTPS upstream support](https://fabiolb.net/feature/https-upstream/) * [Websockets](https://fabiolb.net/feature/websockets/) and * [SSE](https://fabiolb.net/feature/sse/) * [Dynamic reloading without restart](https://fabiolb.net/feature/dynamic-reloading/) * [Traffic shaping](https://fabiolb.net/feature/traffic-shaping/) for "blue/green" deployments, * [Prometheus](https://fabiolb.net/feature/metrics/), * [Circonus](https://fabiolb.net/feature/metrics/), * [Graphite](https://fabiolb.net/feature/metrics/), * [StatsD](https://fabiolb.net/feature/metrics/), * [DataDog](https://fabiolb.net/feature/metrics/) for metrics, * [WebUI](https://fabiolb.net/feature/web-ui/) and * [Advertising BGP anycast addresses](https://fabiolb.net/feature/bgp/) on non-windows platforms. [Watch](https://www.youtube.com/watch?v=gf43TcWjBrE&list=PL81sUbsFNc5b-Gd59Lpz7BW0eHJBt0GvE&index=1) Kelsey Hightower demo Consul, Nomad, Vault and fabio at HashiConf EU 2016. The full documentation is on [fabiolb.net](https://fabiolb.net/) ## Getting started 1. Install from source, [binary](https://github.com/fabiolb/fabio/releases), [Docker](https://hub.docker.com/r/fabiolb/fabio/) or [Homebrew](http://brew.sh). ```shell # go 1.15 or higher is required go install github.com/fabiolb/fabio@latest (>= go1.15) brew install fabio (OSX/macOS stable) brew install --devel fabio (OSX/macOS devel) docker pull fabiolb/fabio (Docker) https://github.com/fabiolb/fabio/releases (pre-built binaries) ``` 2. Register your service in [consul](https://consul.io/). Make sure that each instance registers with a **unique ServiceID** and a service name **without spaces**. 3. Register a **health check** in consul as described [here](https://consul.io/docs/agent/checks.html). By default fabio only watches services which have a **passing** health check, unless overridden with [registry.consul.service.status](https://fabiolb.net/ref/registry.consul.service.status/). 4. Register one `urlprefix-` tag per `host/path` prefix it serves, e.g.: ``` # HTTP/S examples urlprefix-/css # path route urlprefix-i.com/static # host specific path route urlprefix-mysite.com/ # host specific catch all route urlprefix-/foo/bar strip=/foo # path stripping (forward '/bar' to upstream) urlprefix-/foo/bar proto=https # HTTPS upstream urlprefix-/foo/bar proto=https tlsskipverify=true # HTTPS upstream and self-signed cert # TCP examples urlprefix-:3306 proto=tcp # route external port 3306 ``` Make sure the prefix for HTTP routes contains **at least one slash** (`/`). See the full list of options in the [Documentation](https://github.com/fabiolb/fabio/wiki/Routing#config-language). 5. Start fabio without a config file (assuming a running consul agent on `localhost:8500`) Watch the log output how fabio picks up the route to your service. Try starting/stopping your service to see how the routing table changes instantly. 6. Send all your HTTP traffic to fabio on port `9999`. For TCP proxying see [TCP proxy](https://fabiolb.net/feature/tcp-proxy/). 7. Done ## Author and Founder * Frank Schroeder [@magiconair](https://twitter.com/magiconair) ## Maintainers * [Education Networks of America](https://github.com/myENA/) * [Fabio Members](https://github.com/orgs/fabiolb/people) ### Contributors This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. ## License * Contributions up to 14 Apr 2017 before [38f73da](https://github.com/fabiolb/fabio/commit/38f73da6413b68fed1631101ac1d0b79a2fac870) MIT Licensed Copyright (c) 2017 eBay Software Foundation. All rights reserved. * Contributions after 14 Apr 2017 starting with [38f73da](https://github.com/fabiolb/fabio/commit/38f73da6413b68fed1631101ac1d0b79a2fac870) MIT Licensed Copyright (c) 2017-2019 Frank Schroeder. All rights reserved. * Contributions after 22 Jan 2020 starting with [9da7b1b](https://github.com/fabiolb/fabio/commit/9da7b1b6ce0f631f7974e8663b34022c3496dca7#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5) MIT Licensed Copyright (c) 2020 Education Networks of America. All rights reserved. See [LICENSE](https://github.com/fabiolb/fabio/blob/master/LICENSE) for details. ## 2. In-Tree Documentation Chapters (fabiolb/fabio) ## File: README.md --- #### Notes 1) From release 1.6.1 onward, the minimum golang version supported is 1.16. 2) From release 1.6.0 onward, metrics backend statsd is no longer supported. statsd_raw works similarly, though it actually resets counters appropriately. If you are using datadog, you should consider using the new dogstatsd backend, which has support for tags now. Graphite histogram functionality has changed slightly since switching to gokit framework, so something to be aware of. Prometheus functionality is now supported natively. 3) From release 1.5.15 onward, fabio changes the default GOGC from 800 back to the golang default of 100. Apparently this made some sense back in the golang 1.5 days, but with changes introduced with golang 1.12 and others, this is probably no longer a very good default. This is still configurable, as always, but the new default should make the most sense for most users. 4) From release 1.5.14, release hashes are signed with a new PGP key. See details [here](https://fabiolb.net/faq/verifying-releases/). 5) From release 1.5.14 onward, fabio binary releases are compiled with golang 1.15+. This means that the fabio will no longer validate upstream https certificates that do not have SAN extensions matching the server name. This may be a concern if fabio is communicating with https backends with misconfigured certificates. If this is a problem, you can specify `tlsskipverify=true` on the route. --- fabio is a fast, modern, zero-conf load balancing HTTP(S) and TCP router for deploying applications managed by [consul](https://consul.io/). Register your services in consul, provide a health check and fabio will start routing traffic to them. No configuration required. Deployment, upgrading and refactoring has never been easier. fabio is developed and maintained by The Fabio Authors. It powers some of the largest websites in Australia ([gumtree.com.au](http://www.gumtree.com.au)). It delivers 23.000 req/sec every day since Sep 2015 without problems. It integrates with [Consul](https://consul.io/), [Vault](https://vaultproject.io/), [Amazon ELB](https://aws.amazon.com/elasticloadbalancing), [Amazon API Gateway](https://aws.amazon.com/api-gateway/) and more. It supports ([Full feature list](https://fabiolb.net/feature/)) * [TLS termination with dynamic certificate stores](https://fabiolb.net/feature/certificate-stores/) * [Raw TCP proxy](https://fabiolb.net/feature/tcp-proxy/) * [TCP+SNI proxy for full end-to-end TLS](https://fabiolb.net/feature/tcp-sni-proxy/) without decryption * [HTTPS+TCP+SNI proxy for TCP+SNI with HTTPS fallback](https://fabiolb.net/feature/https-tcp-sni-proxy/) * [TCP dynamic proxy](https://fabiolb.net/feature/tcp-dynamic-proxy/) * [HTTPS upstream support](https://fabiolb.net/feature/https-upstream/) * [Websockets](https://fabiolb.net/feature/websockets/) and * [SSE](https://fabiolb.net/feature/sse/) * [Dynamic reloading without restart](https://fabiolb.net/feature/dynamic-reloading/) * [Traffic shaping](https://fabiolb.net/feature/traffic-shaping/) for "blue/green" deployments, * [Prometheus](https://fabiolb.net/feature/metrics/), * [Circonus](https://fabiolb.net/feature/metrics/), * [Graphite](https://fabiolb.net/feature/metrics/), * [StatsD](https://fabiolb.net/feature/metrics/), * [DataDog](https://fabiolb.net/feature/metrics/) for metrics, * [WebUI](https://fabiolb.net/feature/web-ui/) and * [Advertising BGP anycast addresses](https://fabiolb.net/feature/bgp/) on non-windows platforms. [Watch](https://www.youtube.com/watch?v=gf43TcWjBrE&list=PL81sUbsFNc5b-Gd59Lpz7BW0eHJBt0GvE&index=1) Kelsey Hightower demo Consul, Nomad, Vault and fabio at HashiConf EU 2016. The full documentation is on [fabiolb.net](https://fabiolb.net/) ## Getting started 1. Install from source, [binary](https://github.com/fabiolb/fabio/releases), [Docker](https://hub.docker.com/r/fabiolb/fabio/) or [Homebrew](http://brew.sh). ```shell # go 1.15 or higher is required go install github.com/fabiolb/fabio@latest (>= go1.15) brew install fabio (OSX/macOS stable) brew install --devel fabio (OSX/macOS devel) docker pull fabiolb/fabio (Docker) https://github.com/fabiolb/fabio/releases (pre-built binaries) ``` 2. Register your service in [consul](https://consul.io/). Make sure that each instance registers with a **unique ServiceID** and a service name **without spaces**. 3. Register a **health check** in consul as described [here](https://consul.io/docs/agent/checks.html). By default fabio only watches services which have a **passing** health check, unless overridden with [registry.consul.service.status](https://fabiolb.net/ref/registry.consul.service.status/). 4. Register one `urlprefix-` tag per `host/path` prefix it serves, e.g.: ``` # HTTP/S examples urlprefix-/css # path route urlprefix-i.com/static # host specific path route urlprefix-mysite.com/ # host specific catch all route urlprefix-/foo/bar strip=/foo # path stripping (forward '/bar' to upstream) urlprefix-/foo/bar proto=https # HTTPS upstream urlprefix-/foo/bar proto=https tlsskipverify=true # HTTPS upstream and self-signed cert # TCP examples urlprefix-:3306 proto=tcp # route external port 3306 ``` Make sure the prefix for HTTP routes contains **at least one slash** (`/`). See the full list of options in the [Documentation](https://github.com/fabiolb/fabio/wiki/Routing#config-language). 5. Start fabio without a config file (assuming a running consul agent on `localhost:8500`) Watch the log output how fabio picks up the route to your service. Try starting/stopping your service to see how the routing table changes instantly. 6. Send all your HTTP traffic to fabio on port `9999`. For TCP proxying see [TCP proxy](https://fabiolb.net/feature/tcp-proxy/). 7. Done ## Author and Founder * Frank Schroeder [@magiconair](https://twitter.com/magiconair) ## Maintainers * [Education Networks of America](https://github.com/myENA/) * [Fabio Members](https://github.com/orgs/fabiolb/people) ### Contributors This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. ## License * Contributions up to 14 Apr 2017 before [38f73da](https://github.com/fabiolb/fabio/commit/38f73da6413b68fed1631101ac1d0b79a2fac870) MIT Licensed Copyright (c) 2017 eBay Software Foundation. All rights reserved. * Contributions after 14 Apr 2017 starting with [38f73da](https://github.com/fabiolb/fabio/commit/38f73da6413b68fed1631101ac1d0b79a2fac870) MIT Licensed Copyright (c) 2017-2019 Frank Schroeder. All rights reserved. * Contributions after 22 Jan 2020 starting with [9da7b1b](https://github.com/fabiolb/fabio/commit/9da7b1b6ce0f631f7974e8663b34022c3496dca7#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5) MIT Licensed Copyright (c) 2020 Education Networks of America. All rights reserved. See [LICENSE](https://github.com/fabiolb/fabio/blob/master/LICENSE) for details. --- ## File: docs/archetypes/default.md --- title: "{{ replace .TranslationBaseName "-" " " | title }}" date: {{ .Date }} draft: true --- --- ## File: docs/content/cfg/_index.md --- title: "Config Language" weight: 550 --- The routing table is configured with commands in the language specified below. Rules are automatically generated by the configured backend. Additional rules can be stored in the Consul KV store configured by [`registry.consul.kvpath`](/ref/registry.consul.kvpath/) which by default is `/fabio/config`. As of fabio 1.5.7 the path is interpreted as a prefix and the values of all sub keys are appended in alphabetical order. When the [`log.routes.format`](/ref/log.routes.format/) is set to `all` then the routing table contains comments on the source of the fragment. ### Comments Blank lines and lines starting with `#` or `//` are ignored. ### `route add` Add a route for a service `svc` for the `src` (e.g. `/path` or `:port`) to a `dst` (e.g. `URL` or `host:port`). `route add [ weight ][ tags ",,..."][ opts "k1=v1 k2=v2 ..."]` Option | Description ------------------------------------------ | ----------- `allow=ip:10.0.0.0/8,ip:fe80::/10` | Restrict access to source addresses within the `10.0.0.0/8` or `fe80::/10` CIDR mask. All other requests will be denied. `deny=ip:10.0.0.0/8,ip:fe80::1234` | Deny requests that source from the `10.0.0.0/8` CIDR mask or `fe80::1234`. All other requests will be allowed. `strip=/path` | Forward `/path/to/file` as `/to/file` `prepend=/prefix` | Forward `/path/to/file` as `/prefix/path/to/file` `proto=tcp` | Upstream service is TCP, `dst` must be `:port` `pxyproto=true` | Enables PROXY protocol on outbount TCP connection `proto=https` | Upstream service is HTTPS `tlsskipverify=true` | Disable TLS cert validation for HTTPS upstream `host=name` | Set the `Host` header to `name`. If `name == 'dst'` then the `Host` header will be set to the registered upstream host name `register=name` | Register fabio as new service `name`. Useful for registering hostnames for host specific routes. `auth=name` | Specify an auth scheme to use (must be registered with the fabio server using `proxy.auth`) ##### Example ``` # route traffic for product-svc to 1.2.3.4:8000 and :9000 route add product-svc /product http://1.2.3.4:8000 route add product-svc /product http://1.2.3.4:9000 ``` ### `route del` Remove one or more routes which match the given criteria. ``` route del [ [ ]] route del tags ",,..." route del tags ",,..." ``` ##### Example ``` # remove all routes for 'product-svc' route del product-svc # remove all routes for 'product-svc' and /path route del product-svc /path # remove single route route del product-svc /path http://1.2.3.4:8000 # remove all routes for 'product-svc' matching a tag route del product-svc tags "green" # remove all routes matching a tag route del tags "yesterday" ``` ### `route weight` Directs a certain amount of traffic to instances matching certain criteria. The weight `w` is expressed as follows: * `w` is a float > 0 describing a percentage, e.g. 0.5 == 50% * `w <= 0`: means no fixed weighting. Traffic is evenly distributed * `w > 0`: route will receive n% of traffic. If sum(w) > 1 then w is normalized. * `sum(w) >= 1`: only matching services will receive traffic Note that the total sum of traffic sent to all matching routes is `w`%. The order of commands matters but routes are always ordered from most to least specific by prefix length. ``` route weight weight tags ",,..." route weight weight tags ",,..." route weight weight route weight service host/path weight w tags "tag1,tag2" ``` ##### Example ``` # Route 5% of the traffic to product-svc:/path with tags "green" route weight product-svc /path weight .05 tags "green" # Route 5% of the traffic to '/path' to the Go implementation. # Route the rest (95%) to the other implementation route weight /path weight .05 tags "lang=go" # Route 5% of the traffice to '/path' on the product-svc-go route weight product-svc-go /path weight .05 ``` ### Routing rules The routing table contains first all routes with a host sorted by prefix length in descending order and then all routes without a host again sorted by prefix length in descending order. For each incoming request the routing table is searched top to bottom for a matching route. A route matches if either `host/path` or - if there was no match - just `/path` matches. The matching route determines the target URL depending on the configured strategy. `rnd` and `rr` are available with `rnd` being the default. ##### Example The auto-generated routing table is ``` route add service-a www.mp.dev/accounts/ http://host-a:11050/ tags "a,b" route add service-a www.kjca.dev/accounts/ http://host-a:11050/ tags "a,b" route add service-a www.dba.dev/accounts/ http://host-a:11050/ tags "a,b" route add service-b www.mp.dev/auth/ http://host-b:11080/ tags "a,b" route add service-b www.kjca.dev/auth/ http://host-b:11080/ tags "a,b" route add service-b www.dba.dev/auth/ http://host-b:11080/ tags "a,b" ``` The manual configuration under `/fabio/config` is ``` route del service-b www.dba.dev/auth/ route add service-c www.somedomain.com/ http://host-z:12345/ ``` The complete routing table then is ``` route add service-a www.mp.dev/accounts/ http://host-a:11050/ tags "a,b" route add service-a www.kjca.dev/accounts/ http://host-a:11050/ tags "a,b" route add service-a www.dba.dev/accounts/ http://host-a:11050/ tags "a,b" route add service-b www.mp.dev/auth/ http://host-b:11080/ tags "a,b" route add service-b www.kjca.dev/auth/ http://host-b:11080/ tags "a,b" route add service-c www.somedomain.com/ http://host-z:12345/ ``` --- ## File: docs/content/code-of-conduct/_index.md --- title: "Code of Conduct" weight: 1000 --- Be nice and treat others with respect. Please contact a project owner if you need mediation with a dispute. --- ## File: docs/content/contact/_index.md --- title: "Contact" weight: 2000 --- Please create a [GitHub](https://github.com/fabiolb/fabio/issues) issue for all feature requests, bugs and general questions about the project. You may also contact any project owner for other concerns. --- ## File: docs/content/contrib/_index.md --- title: "Contributing" weight: 900 --- Contributions to fabio of any kind are welcome including documentation, examples, feature requests, bug reports, discussions, helping with issues, etc. If you have a question on how or what to contribute just open an issue and indicate that it is a question. --- ## File: docs/content/contrib/development.md --- title: "Development" weight: 200 --- For newcomers to Go, you can't just `git clone` your forked repo and work from there, due to how Go's `GOPATH` works. You can follow the steps below to get started: 1. Fork this repository to your own account (named `myfork` below) 1. Make sure you have [Consul](https://www.consul.io/downloads.html) and [Vault](https://www.vaultproject.io/downloads.html) installed in your `$PATH` 1. `go get github.com/fabiolb/fabio`, change to the directory where the code was cloned (`$GOPATH/src/github.com/fabiolb/fabio`) and add your fork as remote: `git remote add myfork git@github.com:myfork/fabio.git` 1. Hack away! 1. `go fmt` and `make test` your code 1. Commit your changes and *push to your own fork*: `git push myfork` 1. Create a pull-request --- ## File: docs/content/contrib/guidelines.md --- title: "Guidelines" weight: 100 --- ### Your contribution is welcome! To make merging code as seamless as possible we ask for the following: * For small changes and bug fixes go ahead, fork the project, make your changes and send a pull request. Check out the [Development](/contrib/development/) page for some useful tips. * Larger changes should start with a proposal in an issue. This should ensure that the requested change is in line with the project and similar work is not already underway. * Only add libraries if they provide significant value. Consider copying the code (attribution) or writing it yourself. * Manage dependencies with `go mod` and run `go mod vendor` afterwards to sync the `vendor` folder for backwards compatibility. Once you are ready to send in a pull request, be sure to: * Sign the [CLA](https://cla-assistant.io/fabiolb/fabio) * Provide test cases for the critical code which test correctness. If your code is in a performance critical path make sure you have performed some real world measurements to ensure that performance is not degregated. * `go fmt` and `make test` your code * Squash your change into a single commit with the exception of additional libraries. * Write a good commit message. --- ## File: docs/content/deploy/_index.md --- title: "Deployment" weight: 300 --- The main use-case for fabio is to distribute incoming HTTP(S) and TCP requests from the internet to frontend (FE) services which can handle these requests. In this scenario the FE services then use the service discovery feature in [Consul](https://consul.io/) to find backend (BE) services they need in order to serve the request. That means that fabio is currently not used as an FE-BE or BE-BE router to route traffic among the services themselves since the service discovery of [Consul](https://consul.io/) already solves that problem. Having said that, there is nothing that inherently prevents fabio from being used that way. It just means that we are not doing it. --- ## File: docs/content/deploy/amazon-api-gw.md --- title: "Amazon API Gateway" weight: 500 --- You can deploy fabio as the target of an [Amazon API Gateway](https://aws.amazon.com/api-gateway/). internet -- HTTP/HTTPS --> API GW -+- HTTP -> fabio -+-> service-b (host-b) or behind an ELB with PROXY protocol support: +- HTTP w/PROXY -> fabio -+-> service-a (host-a) | | internet -- HTTP/HTTPS --> API GW --> ELB -+- HTTP w/PROXY -> fabio -+-> service-b (host-b) | | +- HTTP w/PROXY -> fabio -+-> service-c (host-c) You can authenticate calls from the API Gateway with a client certificate. This requires that you configure an HTTPS listener on fabio with a valid certificate. internet -- HTTPS --> API GW -+- HTTPS w/client cert -> fabio -+-> service To enable fabio to validate the Amazon generated certificate you need to configure the `aws.apigw.cert.cn` as follows: proxy.addr = 1.2.3.4:9999;your/cert.pem;your/key.pem;api-gw-cert.pem aws.apigw.cert.cn = ApiGateway `api-gw-cert.pem` is the certificate generated in the AWS Management Console. `your/cert.pem` and `your/key.pem` is the certificate/key pair for the HTTPS certificate. Since the Amazon API Gateway certificates don't have the `CA` flag set fabio needs to trust them for the client certificate authentication to work. Otherwise, you will get an `TLS handshake error: failed to verify client's certificate`. See [Issue 108](https://github.com/fabiolb/fabio/issues/108) for details. **Note:** The `aws.apigw.cert.cn` parameter will not be supported in version 1.2 and later which support dynamic certificate stores. You will have to add the `caupgcn=ApiGateway` parameter to the certificate source configuration instead. See [Certificate Stores](/feature/certificate-stores/) for more detail. --- METRICS --- - Files Extracted: 11 - Estimated Token Budget: ~6636 tokens - Recency Window: Active (< 180 days) - Canonical Reference: https://codewiki.google/github.com/fabiolb/fabio