Skip to content

Commit

Permalink
security: Google Vulnerability Reward Program (VRP) (#11005)
Browse files Browse the repository at this point in the history
This PR povides the documentation and an accompanying set of Docker images for Envoy's participation in the Google Vulnerability Reward Program (VRP), see https://www.google.com/about/appsecurity/reward-program/.

The starting point is a fairly conservative Envoy use case, over time we will grow this.

Signed-off-by: Harvey Tuch <[email protected]>
  • Loading branch information
htuch authored May 27, 2020
1 parent f13ea5b commit 1ef01c0
Show file tree
Hide file tree
Showing 13 changed files with 458 additions and 101 deletions.
22 changes: 22 additions & 0 deletions ci/Dockerfile-envoy-google-vrp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM envoyproxy/envoy:local

RUN apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y libc++1 supervisor gdb strace tshark \
&& apt-get autoremove -y \
&& apt-get clean \
&& rm -rf /tmp/* /var/tmp/* \
&& rm -rf /var/lib/apt/lists/*

ADD configs/google-vrp/envoy-edge.yaml /etc/envoy/envoy-edge.yaml
ADD configs/google-vrp/envoy-origin.yaml /etc/envoy/envoy-origin.yaml
ADD configs/google-vrp/launch_envoy.sh /usr/local/bin/launch_envoy.sh
ADD configs/google-vrp/supervisor.conf /etc/supervisor.conf
ADD test/config/integration/certs/serverkey.pem /etc/envoy/certs/serverkey.pem
ADD test/config/integration/certs/servercert.pem /etc/envoy/certs/servercert.pem
# ADD %local envoy bin% /usr/local/bin/envoy

EXPOSE 10000
EXPOSE 10001

CMD ["supervisord", "-c", "/etc/supervisor.conf"]
7 changes: 5 additions & 2 deletions ci/docker_ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ set -e
# This prefix is altered for the private security images on setec builds.
DOCKER_IMAGE_PREFIX="${DOCKER_IMAGE_PREFIX:-envoyproxy/envoy}"

# "-google-vrp" must come afer "" to ensure we rebuild the local base image dependency.
BUILD_TYPES=("" "-alpine" "-alpine-debug" "-google-vrp")

# Test the docker build in all cases, but use a local tag that we will overwrite before push in the
# cases where we do push.
for BUILD_TYPE in "" "-alpine" "-alpine-debug"; do
for BUILD_TYPE in "${BUILD_TYPES[@]}"; do
docker build -f ci/Dockerfile-envoy"${BUILD_TYPE}" -t "${DOCKER_IMAGE_PREFIX}${BUILD_TYPE}:local" .
done

Expand Down Expand Up @@ -38,7 +41,7 @@ fi

docker login -u "$DOCKERHUB_USERNAME" -p "$DOCKERHUB_PASSWORD"

for BUILD_TYPE in "" "-alpine" "-alpine-debug"; do
for BUILD_TYPE in ${BUILD_TYPES}; do
docker tag "${DOCKER_IMAGE_PREFIX}${BUILD_TYPE}:local" "${DOCKER_IMAGE_PREFIX}${BUILD_TYPE}${IMAGE_POSTFIX}:${IMAGE_NAME}"
docker push "${DOCKER_IMAGE_PREFIX}${BUILD_TYPE}${IMAGE_POSTFIX}:${IMAGE_NAME}"

Expand Down
53 changes: 53 additions & 0 deletions ci/docker_rebuild_google-vrp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/bin/bash

# Script to rebuild Dockerfile-envoy-google-vrp locally (i.e. not in CI) for development purposes.
# This makes use of the latest envoy-dev base image on Docker Hub as the base and takes an
# optional local path for an Envoy binary. When a custom local Envoy binary is used, the script
# switches to using ${BASE_DOCKER_IMAGE} for the build, which should be configured to provide
# compatibility with your local build environment (specifically glibc).
#
# Usage:
#
# Basic rebuild of Docker image (tagged envoy-google-vrp:local):
#
# ./ci/docker_rebuild_google-vrp.sh
#
# Basic rebuild of Docker image (tagged envoy-google-vrp:local) with some local Envoy binary:
#
# bazel build //source/exe:envoy-static --config=libc++ -copt
# ./ci/docker_rebuild_google-vrp.sh bazel-bin/source/exe/envoy-static

set -e

# This should match your local machine if you are building custom Envoy binaries outside of Docker.
BASE_DOCKER_IMAGE="ubuntu:20.04"

declare -r BUILD_DIR="$(mktemp -d)"
cp ci/Dockerfile-envoy-google-vrp "${BUILD_DIR}"
declare -r DOCKER_BUILD_FILE="${BUILD_DIR}"/Dockerfile-envoy-google-vrp

# If we have a local Envoy binary, use a variant of the build environment that supports it.
if [[ -n "$1" ]]
then
# Switch to a base image similar to the local build environment. This provides compatibility of
# locally built Envoy and glibc in the Docker env.
sed -i -e "s#envoyproxy/envoy:local#${BASE_DOCKER_IMAGE}#" "${DOCKER_BUILD_FILE}"
# Copy the binary to deal with symlinks in Bazel cache and Docker daemon confusion.
declare -r LOCAL_ENVOY="envoy-binary"
cp -f "$1" "${PWD}/${LOCAL_ENVOY}"
sed -i -e "s@# ADD %local envoy bin%@ADD ${LOCAL_ENVOY}@" "${DOCKER_BUILD_FILE}"
else
# Don't use the local envoy-dev, but pull from Docker Hub instead, this avoids having to rebuild
# this local dep which is fairly stable.
sed -i -e "s#envoyproxy/envoy:local#envoyproxy/envoy-dev:latest#" "${DOCKER_BUILD_FILE}"
fi

cat "${DOCKER_BUILD_FILE}"

docker build -t "envoy-google-vrp:local" -f "${DOCKER_BUILD_FILE}" .

if [[ -n "$1" ]]
then
rm -f "${LOCAL_ENVOY}"
fi
rm -r "${BUILD_DIR}"
2 changes: 2 additions & 0 deletions configs/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ envoy_py_test_binary(
filegroup(
name = "configs",
srcs = [
"google-vrp/envoy-edge.yaml",
"google-vrp/envoy-origin.yaml",
"original-dst-cluster/proxy_config.yaml",
] + select({
"//bazel:apple": [],
Expand Down
92 changes: 92 additions & 0 deletions configs/google-vrp/envoy-edge.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
overload_manager:
refresh_interval: 0.25s
resource_monitors:
- name: "envoy.resource_monitors.fixed_heap"
typed_config:
"@type": type.googleapis.com/envoy.config.resource_monitor.fixed_heap.v2alpha.FixedHeapConfig
# TODO: Tune for your system.
max_heap_size_bytes: 1073741824 # 1 GiB
actions:
- name: "envoy.overload_actions.shrink_heap"
triggers:
- name: "envoy.resource_monitors.fixed_heap"
threshold:
value: 0.90
- name: "envoy.overload_actions.stop_accepting_requests"
triggers:
- name: "envoy.resource_monitors.fixed_heap"
threshold:
value: 0.95

static_resources:
listeners:
- name: listener_https
address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 10000
per_connection_buffer_limit_bytes: 32768 # 32 KiB
filter_chains:
- transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_certificates:
- certificate_chain: { filename: "certs/servercert.pem" }
private_key: { filename: "certs/serverkey.pem" }
# Uncomment if Envoy is behind a load balancer that exposes client IP address using the PROXY protocol.
# use_proxy_proto: true
filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
use_remote_address: true
common_http_protocol_options:
idle_timeout: 3600s # 1 hour
headers_with_underscores_action: REJECT_REQUEST
http2_protocol_options:
max_concurrent_streams: 100
initial_stream_window_size: 65536 # 64 KiB
initial_connection_window_size: 1048576 # 1 MiB
stream_idle_timeout: 300s # 5 mins, must be disabled for long-lived and streaming requests
request_timeout: 300s # 5 mins, must be disabled for long-lived and streaming requests
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
# The exact route table is not super important in this example (this is the model
# for the Google VRP scenario).
routes:
- match:
prefix: "/content"
route:
cluster: service_foo
idle_timeout: 15s # must be disabled for long-lived and streaming requests
- match:
prefix: "/"
direct_response:
status: 403
body:
inline_string: "denied\n"
http_filters:
- name: envoy.filters.http.router
clusters:
name: service_foo
connect_timeout: 5s
per_connection_buffer_limit_bytes: 32768 # 32 KiB
load_assignment:
cluster_name: service_foo
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 10002
http2_protocol_options:
initial_stream_window_size: 65536 # 64 KiB
initial_connection_window_size: 1048576 # 1 MiB
64 changes: 64 additions & 0 deletions configs/google-vrp/envoy-origin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
overload_manager:
refresh_interval: 0.25s
resource_monitors:
- name: "envoy.resource_monitors.fixed_heap"
typed_config:
"@type": type.googleapis.com/envoy.config.resource_monitor.fixed_heap.v2alpha.FixedHeapConfig
max_heap_size_bytes: 1073741824 # 1 GiB
actions:
- name: "envoy.overload_actions.shrink_heap"
triggers:
- name: "envoy.resource_monitors.fixed_heap"
threshold:
value: 0.95
- name: "envoy.overload_actions.stop_accepting_requests"
triggers:
- name: "envoy.resource_monitors.fixed_heap"
threshold:
value: 0.98

static_resources:
listeners:
- name: listener_0
address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 10002
per_connection_buffer_limit_bytes: 32768
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
use_remote_address: true
common_http_protocol_options:
idle_timeout: 3600s # 1 hour
headers_with_underscores_action: REJECT_REQUEST
http2_protocol_options:
max_concurrent_streams: 100
initial_stream_window_size: 65536 # 64 KiB
initial_connection_window_size: 1048576 # 1 MiB
stream_idle_timeout: 300s # 5 mins, must be disabled for long-lived and streaming requests
request_timeout: 300s # 5 mins, must be disabled for long-lived and streaming requests
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
path: "/blockedz"
direct_response:
status: 200
body:
inline_string: "hidden treasure\n"
- match:
prefix: "/"
direct_response:
status: 200
body:
inline_string: "normal\n"
http_filters:
- name: envoy.filters.http.router
4 changes: 4 additions & 0 deletions configs/google-vrp/launch_envoy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

cd /etc/envoy
envoy "$@"
16 changes: 16 additions & 0 deletions configs/google-vrp/supervisor.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[supervisord]
nodaemon=true

[program:envoy-edge]
command=launch_envoy.sh -c /etc/envoy/envoy-edge.yaml %(ENV_ENVOY_EDGE_EXTRA_ARGS)s
--log-format "(edge)[%%Y-%%m-%%d %%T.%%e][%%t][%%l][%%n] %%v" --base-id 0
redirect_stderr=true
stdout_logfile_maxbytes=0
stdout_logfile=/dev/stdout

[program:envoy-origin]
command=launch_envoy.sh -c /etc/envoy/envoy-origin.yaml %(ENV_ENVOY_ORIGIN_EXTRA_ARGS)s
--log-format "(origin)[%%Y-%%m-%%d %%T.%%e][%%t][%%l][%%n] %%v" --base-id 1
redirect_stderr=true
stdout_logfile_maxbytes=0
stdout_logfile=/dev/stdout
13 changes: 9 additions & 4 deletions docs/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ else
export ENVOY_BLOB_SHA="$BUILD_SHA"
fi

SCRIPT_DIR=$(dirname "$0")
API_DIR=$(dirname "$dir")/api
SCRIPT_DIR="$(dirname "$0")"
SRC_DIR="$(dirname "$dir")"
API_DIR="${SRC_DIR}"/api
CONFIGS_DIR="${SRC_DIR}"/configs
BUILD_DIR=build_docs
[[ -z "${DOCS_OUTPUT_DIR}" ]] && DOCS_OUTPUT_DIR=generated/docs
[[ -z "${GENERATED_RST_DIR}" ]] && GENERATED_RST_DIR=generated/rst
Expand Down Expand Up @@ -115,9 +117,12 @@ generate_api_rst v3
find "${GENERATED_RST_DIR}"/api-v3 -name "*.rst" -print0 | xargs -0 sed -i -e "s#envoy_api_#envoy_v3_api_#g"
find "${GENERATED_RST_DIR}"/api-v3 -name "*.rst" -print0 | xargs -0 sed -i -e "s#config_resource_monitors#v3_config_resource_monitors#g"

# xDS protocol spec.
mkdir -p ${GENERATED_RST_DIR}/api-docs

cp -f $API_DIR/xds_protocol.rst "${GENERATED_RST_DIR}/api-docs/xds_protocol.rst"
cp -f "${API_DIR}"/xds_protocol.rst "${GENERATED_RST_DIR}/api-docs/xds_protocol.rst"
# Edge hardening example YAML.
mkdir -p "${GENERATED_RST_DIR}"/configuration/best_practices
cp -f "${CONFIGS_DIR}"/google-vrp/envoy-edge.yaml "${GENERATED_RST_DIR}"/configuration/best_practices

rsync -rav $API_DIR/diagrams "${GENERATED_RST_DIR}/api-docs"

Expand Down
Loading

0 comments on commit 1ef01c0

Please sign in to comment.