Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP][Docker] Add SSL proxy for being able to run using http/2 #257

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions doc/docker/Dockerfile-nginx-ssl-proxy
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM nginx:stable-perl
# Based on: https://github.com/clamorisse/nginx-ssl-container

RUN mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak

RUN apt-get update -q -y \
&& apt-get install -q -y --no-install-recommends ca-certificates openssl \
&& rm -rf /var/lib/apt/lists/*

ADD entrypoint/ssl-proxy/nginx.conf /etc/nginx/

COPY entrypoint/ssl-proxy/docker-ssl-entrypoint /usr/local/bin/

EXPOSE 443

ENTRYPOINT ["docker-ssl-entrypoint"]
CMD ["nginx", "-g", "daemon off;"]
28 changes: 28 additions & 0 deletions doc/docker/entrypoint/ssl-proxy/docker-ssl-entrypoint
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/sh -e
# Based on among others: https://github.com/fsouza/docker-ssl-proxy

DOMAIN=${DOMAIN:-localhost}

CA_DIR=/etc/nginx/ca

# If this change, then you'1ll also need ot change nginx.conf
OUTPUT_DIR=/etc/nginx/certs

mkdir -p $OUTPUT_DIR $CA_DIR

# Generate the root CA if it doesn't exist
if [ ! -f ${CA_DIR}/rootCA.crt ]; then
openssl genrsa -out ${CA_DIR}/rootCA.key 1024
openssl req -x509 -new -nodes -key ${CA_DIR}/rootCA.key -sha256 -days 1024 -subj "/C=US/ST=Denial/L=Springfield/O=DisRoot/CN=CompanyRoot" -out ${CA_DIR}/rootCA.crt
fi

# Generate the certificate, if it doesn't exist
if [ ! -f ${OUTPUT_DIR}/key.pem ]; then
openssl genrsa -out ${OUTPUT_DIR}/key.pem 1024
openssl req -new -sha256 -key ${OUTPUT_DIR}/key.pem -nodes -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=${DOMAIN}" -out ${OUTPUT_DIR}/csr.pem
openssl x509 -req -in ${OUTPUT_DIR}/csr.pem -CA ${CA_DIR}/rootCA.crt -CAkey ${CA_DIR}/rootCA.key -CAcreateserial -out ${OUTPUT_DIR}/cert.pem
fi

echo ">> exec CMD"
echo "$@"
exec "$@"
52 changes: 52 additions & 0 deletions doc/docker/entrypoint/ssl-proxy/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
user nginx;
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

load_module /etc/nginx/modules/ngx_http_perl_module.so;

# To pass in the public facing forward port we want to set
env X_FORWARD_PORT;

events {
worker_connections 1024;
}

http {
access_log off;

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 15;

# Get SSL port to use from X_FORWARD_PORT env variable, or fallback to 443
perl_set $x_forward_port 'sub { return $ENV{"X_FORWARD_PORT"} || 443; }';

server {
listen 443 ssl http2;

client_max_body_size 40m;
ssl_certificate /etc/nginx/certs/cert.pem;
ssl_certificate_key /etc/nginx/certs/key.pem;

ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;

location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $x_forward_port;
proxy_set_header Host $host;

proxy_pass http://varnish:80;
}
}
}
2 changes: 1 addition & 1 deletion doc/docker/entrypoint/varnish/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,4 @@ while (( "$#" )); do
shift
done

varnishd -F -a :80 -T :6082 -f /etc/varnish/default.vcl -s malloc,${VARNISH_MALLOC_SIZE}
varnishd -F -a :80 -T :6082 -f /etc/varnish/default.vcl -s malloc,${VARNISH_MALLOC_SIZE} -p feature=+http2
5 changes: 5 additions & 0 deletions doc/docker/entrypoint/varnish/parameters.vcl
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,8 @@ acl debuggers {
"127.0.0.1";
"172.16.0.0"/20;
}

// ACL for trusted proxies IP
acl proxies {
"ssl";
}
16 changes: 15 additions & 1 deletion doc/docker/varnish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ services:
app:
environment:
- SYMFONY_HTTP_CACHE=0
- SYMFONY_TRUSTED_PROXIES=varnish
- SYMFONY_TRUSTED_PROXIES=ssl,varnish
- HTTPCACHE_PURGE_SERVER=http://varnish
- HTTPCACHE_PURGE_TYPE=http

Expand All @@ -29,6 +29,20 @@ services:
- backend
command: ["--acl-add", "app"]

ssl:
build:
context: .
dockerfile: Dockerfile-nginx-ssl-proxy
ports:
- "8443:443"
environment:
- X_FORWARD_PORT=8443
depends_on:
- varnish
networks:
- frontend
- backend

## DEBUG??
# In need of debugging all request going to Varnish, use varnishlog, example:
# docker-compose exec varnish varnishlog -c -i ReqURL,ReqMethod -I ReqHeader:xkey
Expand Down
5 changes: 5 additions & 0 deletions doc/varnish/vcl/parameters.vcl
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@ acl debuggers {
"127.0.0.1";
"192.168.0.0"/16;
}

// ACL for trusted proxies IP
acl proxies {
"127.0.0.1";
}
12 changes: 7 additions & 5 deletions doc/varnish/vcl/varnish4_xkey.vcl
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ sub vcl_recv {
// To be removed in Symfony 3.3
unset req.http.Forwarded;

// Ensure that the Symfony Router generates URLs correctly with Varnish
if (req.http.X-Forwarded-Proto == "https" ) {
set req.http.X-Forwarded-Port = "443";
} else {
set req.http.X-Forwarded-Port = "80";
// Ensure that the Symfony Router generates URLs correctly with Varnish, if port is not set by trusted proxy already
if (! req.http.X-Forwarded-Port || ! client.ip ~ proxies) {
if (req.http.X-Forwarded-Proto == "https" ) {
set req.http.X-Forwarded-Port = "443";
} else {
set req.http.X-Forwarded-Port = "80";
}
}

// Trigger cache purge if needed
Expand Down
9 changes: 7 additions & 2 deletions web/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,14 @@
$request = Request::createFromGlobals();

// If you are behind one or more trusted reverse proxies, you might want to set them in SYMFONY_TRUSTED_PROXIES environment
// variable in order to get correct client IP
// variable in order to get correct client IP, also by default supports passing in host name to lookup DNS A record (IPv4)
if ($trustedProxies = getenv('SYMFONY_TRUSTED_PROXIES')) {
Request::setTrustedProxies(explode(',', $trustedProxies));
Request::setTrustedProxies(array_map(
function ($adr) {
return is_string($adr) ? gethostbyname($adr) : $adr;
},
explode(',', $trustedProxies)
));
}

$response = $kernel->handle($request);
Expand Down