consul/website/source/docs/connect/proxies.html.md

8.0 KiB

layout page_title sidebar_current description
docs Connect - Proxies docs-connect-proxies A Connect-aware proxy enables unmodified applications to use Connect. A per-service proxy sidecar transparently handles inbound and outbound service connections, automatically wrapping and verifying TLS connections.

Connect Proxies

A Connect-aware proxy enables unmodified applications to use Connect. A per-service proxy sidecar transparently handles inbound and outbound service connections, automatically wrapping and verifying TLS connections.

When a proxy is used, the actual service being proxied should only accept connections on a loopback address. This requires all external connections to be established via the Connect protocol to provide authentication and authorization.

Consul supports both managed and unmanaged proxies. A managed proxy is started, configured, and stopped by Consul. An unmanaged proxy is the responsibility of the user, like any other Consul service.

Managed Proxies

Managed proxies are started, configured, and stopped by Consul. They are enabled via basic configurations within the service definition. This is the easiest way to start a proxy and allows Consul users to begin using Connect with only a small configuration change.

Managed proxies also offer the best security. Managed proxies are given a unique proxy-specific ACL token that allows read-only access to Connect information for the specific service the proxy is representing. This ACL token is more restrictive than can be currently expressed manually in an ACL policy.

The default managed proxy is a basic proxy built-in to Consul and written in Go. Having a basic built-in proxy allows Consul to have a sane default with performance that is good enough for most workloads. In some basic benchmarks, the service-to-service communication over the built-in proxy could sustain 5 Gbps with a per-hop latency of less than X microseconds. Therefore, the performance impact of even the basic built-in proxy is minimal.

Consul will be integrating with advanced proxies in the near future to support more complex configurations and higher performance. The configuration below is all for the built-in proxy.

-> Security note: 1.) Managed proxies can only be configured via agent configuration files. They cannot be registered via the HTTP API. And 2.) Managed proxies are not started at all if Consul is running as root. Both of these default configurations help prevent arbitrary process execution or privilege escalation. This behavior can be configured per-agent.

Minimal Configuration

Managed proxies are configured within a service definition. The simplest possible managed proxy configuration is an empty configuration. This enables the default managed proxy and starts a listener for that service:

{
  "service": {
    "name": "redis",
    "port": 6379,
    "connect": { "proxy": {} }
  }
}

The listener is started on random port within the configured Connect port range. It can be discovered using the DNS interface or Catalog API. In most cases, service-to-service communication is established by a proxy configured with upstreams (described below), which handle the discovery transparently.

Upstream Configuration

To transparently discover and establish Connect-based connections to dependencies, they must be configured with a static port on the managed proxy configuration:

{
  "service": {
    "name": "web",
    "port": 8080,
    "connect": {
      "proxy": {
        "config": {
          "upstreams": [{
            "destination_name": "redis",
            "local_bind_port": 1234
          }]
        }
      }
    }
  }
}

In the example above, "redis" is configured as an upstream with static port 1234 for service "web". When a TCP connection is established on port 1234, the proxy will find Connect-compatible "redis" services via Consul service discovery and establish a TLS connection identifying as "web".

~> Security: Any application that can communicate to the configured static port will be able to masquerade as the source service ("web" in the example above). You must either trust any loopback access on that port or use namespacing techniques provided by your operating system.

Prepared Query Upstreams

The upstream destination may also be a prepared query. This allows complex service discovery behavior such as connecting to the nearest neighbor or filtering by tags.

For example, given a prepared query named "nearest-redis" that is configured to route to the nearest Redis instance, an upstream can be configured to route to this query. In the example below, any TCP connection to port 1234 will attempt a Connect-based connection to the nearest Redis service.

{
  "service": {
    "name": "web",
    "port": 8080,
    "connect": {
      "proxy": {
        "config": {
          "upstreams": [{
            "destination_name": "redis",
            "destination_type": "prepared_query",
            "local_bind_port": 1234
          }]
        }
      }
    }
  }
}

-> Note: Connect does not currently support cross-datacenter service communication. Therefore, prepared queries with Connect should only be used to discover services within a single datacenter. See Multi-Datacenter Connect for more information.

Dynamic Upstreams

If an application requires dynamic dependencies that are only available at runtime, it must currently natively integrate with Connect. After natively integrating, the HTTP API or DNS interface can be used.

Custom Managed Proxy

Custom proxies can also be configured to run as a managed proxy. To configure custom proxies, specify an alternate command to execute for the proxy:

{
  "service": {
    "name": "web",
    "port": 8080,
    "connect": {
      "proxy": {
        "exec_mode": "daemon",
        "command":   ["/usr/bin/my-proxy", "-flag-example"]
      }
    }
  }
}

The exec_mode value specifies how the proxy is executed. The only supported value at this time is "daemon". The command is the binary and any arguments to execute. The "daemon" mode expects a proxy to run as a long-running, blocking process. It should not double-fork into the background. The custom proxy should retrieve its configuration (such as the port to run on) via the custom proxy integration APIs.

The default proxy command can be changed at an agent-global level in the agent configuration. An example in HCL format is shown below.

connect {
  proxy_defaults {
    command = ["/usr/bin/my-proxy"]
  }
}

With this configuration, all services registered without an explicit proxy command will use my-proxy instead of the default built-in proxy.

Unmanaged Proxies

Unmanaged proxies are regular Consul services that are registered as a proxy type and declare the service they represent. The proxy process must be started, configured, and stopped manually by some external process such as an operator or scheduler.

To declare a service as a proxy, the service definition must contain at least two additional fields:

  • Kind (string) must be set to connect-proxy. This declares that the service is a proxy type.

  • ProxyDestination (string) must be set to the service that this proxy is representing.

  • Port must be set so that other Connect services can discover the exact address for connections. Address is optional if the service is being registered against an agent, since it'll inherit the node address.

Example:

{
  "Name": "redis-proxy",
  "Kind": "connect-proxy",
  "ProxyDestination": "redis",
  "Port": 8181
}

With this service registered, any Connect proxies searching for a Connect-capable endpoint for "redis" will find this proxy.