Skip to content

Commit fa5d130

Browse files
Merge pull request #3096 from johanneswuerbach/ec2-websockets
WebSockets on EC2
2 parents 84cd7d0 + 4f634ed commit fa5d130

6 files changed

Lines changed: 87 additions & 11 deletions

File tree

contrib/ec2/deis.template.json

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,20 +287,29 @@
287287
"HealthCheck": {
288288
"HealthyThreshold": "4",
289289
"Interval": "15",
290-
"Target": "HTTP:80/health-check",
290+
"Target": "TCP:80",
291291
"Timeout": "5",
292292
"UnhealthyThreshold": "2"
293293
},
294294
"Subnets": [
295295
{ "Ref" : "Subnet1" },
296296
{ "Ref" : "Subnet2" }
297297
],
298+
"Policies" : [{
299+
"PolicyName" : "EnableProxyProtocol",
300+
"PolicyType" : "ProxyProtocolPolicyType",
301+
"Attributes" : [{
302+
"Name" : "ProxyProtocol",
303+
"Value" : "true"
304+
}],
305+
"InstancePorts" : ["80", "443"]
306+
}],
298307
"Listeners": [
299308
{
300309
"InstancePort": "80",
301-
"InstanceProtocol": "HTTP",
310+
"InstanceProtocol": "TCP",
302311
"LoadBalancerPort": "80",
303-
"Protocol": "HTTP"
312+
"Protocol": "TCP"
304313
},
305314
{
306315
"InstancePort": "443",

contrib/ec2/provision-ec2-cluster.sh

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,15 @@ SLEEPTIME=10
5555
COUNTER=1
5656
INSTANCE_IDS=""
5757
until [ $(wc -w <<< $INSTANCE_IDS) -eq $DEIS_NUM_INSTANCES -a "$STACK_STATUS" = "CREATE_COMPLETE" ]; do
58-
if [ $COUNTER -gt $ATTEMPTS ]; then
58+
if [ $COUNTER -gt $ATTEMPTS ]; then
5959
echo "Provisioning instances failed (timeout, $(wc -w <<< $INSTANCE_IDS) of $DEIS_NUM_INSTANCES provisioned after 10m)"
6060
echo "Destroying stack $STACK_NAME"
6161
bailout
6262
exit 1
6363
fi
6464

6565
STACK_STATUS=$(aws --output text cloudformation describe-stacks --stack-name $STACK_NAME --query 'Stacks[].StackStatus')
66-
if [ $STACK_STATUS != "CREATE_IN_PROGRESS" -a $STACK_STATUS != "CREATE_COMPLETE" ] ; then
66+
if [ $STACK_STATUS != "CREATE_IN_PROGRESS" -a $STACK_STATUS != "CREATE_COMPLETE" ] ; then
6767
echo "error creating stack: "
6868
aws --output text cloudformation describe-stack-events \
6969
--stack-name $STACK_NAME \
@@ -127,3 +127,20 @@ echo "Using ELB $ELB_NAME at $ELB_DNS_NAME"
127127
128128
echo_green "Your Deis cluster has been successfully deployed to AWS CloudFormation and is started."
129129
echo_green "Please continue to follow the instructions in the documentation."
130+
131+
FIRST_INSTANCE=$(aws ec2 describe-instances \
132+
--filters Name=tag:aws:cloudformation:stack-name,Values=$STACK_NAME Name=instance-state-name,Values=running \
133+
--query 'Reservations[].Instances[].[PublicIpAddress]' \
134+
--output text | head -1)
135+
echo_green "Setting DEISCTL_TUNNEL=$FIRST_INSTANCE"
136+
export DEISCTL_TUNNEL=$FIRST_INSTANCE
137+
echo_green "Enabling proxy protocol"
138+
139+
if ! deisctl config router set proxyProtocol=1; then
140+
echo_red "#"
141+
echo_red "# Enabling proxy protocol failed, please enable proxy protocol "
142+
echo_red "# manually after finishing your deis cluster installation."
143+
echo_red "#"
144+
echo_red "# deisctl config router set proxyProtocol=1"
145+
echo_red "#"
146+
fi

docs/customizing_deis/router_settings.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ setting description
6565
/deis/router/sslCert cluster-wide SSL certificate
6666
/deis/router/sslKey cluster-wide SSL private key
6767
/deis/router/workerProcesses nginx number of worker processes to start (default: auto i.e. available CPU cores)
68+
/deis/router/proxyProtocol nginx PROXY protocol enabled
69+
/deis/router/proxyRealIpCidr nginx IP with CIDR used by the load balancer in front of deis-router (default: 10.0.0.0/8)
6870
/deis/services/* healthy application containers reported by deis/publisher
6971
/deis/store/gateway/host host of the store gateway component (set by store-gateway)
7072
/deis/store/gateway/port port of the store gateway component (set by store-gateway)
@@ -90,3 +92,22 @@ Be sure that your custom image functions in the same way as the `stock router im
9092
Deis. Specifically, ensure that it sets and reads appropriate etcd keys.
9193

9294
.. _`stock router image`: https://github.com/deis/deis/tree/master/router
95+
96+
PROXY Protocol
97+
---------------
98+
PROXY is a simple protocol supported by nginx, HAProxy, Amazon ELB, and others. It provides a method
99+
to obtain information about the original requests IP address sent to a load
100+
balancer in front of Deis :ref:`router`.
101+
102+
The Protocol works by prepending, for example, the following to the request:
103+
104+
.. code-block:: text
105+
106+
PROXY TCP4 129.164.129.164\r\n
107+
108+
The :ref:`router` will pick up the IP information and forward it to the application in the
109+
``X-Forwarded-For`` header.
110+
111+
Load Balancers supporting the HTTP protocol may not need this, except in cases where one would run
112+
WebSockets on a Load Balancer without support for WebSockets (for example AWS ELB) and one also
113+
wants to know the IP address of the original request.

docs/installing_deis/aws.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,13 @@ Run the cloudformation provision script to spawn a new CoreOS cluster:
189189
The default name of the CloudFormation stack will be ``deis``. You can specify a different name
190190
with ``./provision-ec2-cluster.sh <name>``.
191191

192+
Remote IPs behind your ELB
193+
--------------------------
194+
195+
The ELB you just created is load-balancing raw TCP connections, which is required for custom domain SSL
196+
and WebSockets. As remote IPs are by default not visible behind a TCP-Proxy, the ELB and your cluster routers
197+
were created with `Proxy Protocol`_ enabled.
198+
192199

193200
Configure DNS
194201
-------------
@@ -229,3 +236,4 @@ Please reference the AWS documentation for `more information about CloudFormatio
229236
.. _`PyYAML`: http://pyyaml.org/
230237
.. _`update_ec2_cluster.sh`: https://github.com/deis/deis/blob/master/contrib/ec2/update-ec2-cluster.sh
231238
.. _`More information about CloudFormation stack updates`: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks.html
239+
.. _`Proxy Protocol`: http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/enable-proxy-protocol.html

router/image/templates/deis.conf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
server_name_in_redirect off;
22
port_in_redirect off;
3-
listen 80;
3+
listen 80{{ if .deis_router_proxyProtocol }} proxy_protocol{{ end }};
44

55
{{ if .deis_router_sslCert }}
6-
listen 443 ssl spdy;
6+
listen 443 ssl spdy{{ if .deis_router_proxyProtocol }} proxy_protocol{{ end }};
77
ssl_certificate /etc/ssl/deis.cert;
88
ssl_certificate_key /etc/ssl/deis.key;
99
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

router/image/templates/nginx.conf

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,12 @@ http {
4747

4848
client_max_body_size {{ or (.deis_router_bodySize) "1m" }};
4949

50-
log_format upstreaminfo '[$time_local] - $remote_addr - $remote_user - $status - "$request" - $bytes_sent - "$http_referer" - "$http_user_agent" - "$server_name" - $upstream_addr - $http_host - $upstream_response_time - $request_time';
50+
{{ $useProxyProtocol := or (.deis_router_proxyProtocol) "false" }}{{ if ne $useProxyProtocol "false" }}
51+
set_real_ip_from {{ or (.deis_router_proxyRealIpCidr) "10.0.0.0/8" }};
52+
real_ip_header proxy_protocol;
53+
{{ end }}
54+
55+
log_format upstreaminfo '[$time_local] - {{ if .deis_router_proxyProtocol }}$proxy_protocol_addr{{ else }}$remote_addr{{ end }} - $remote_user - $status - "$request" - $bytes_sent - "$http_referer" - "$http_user_agent" - "$server_name" - $upstream_addr - $http_host - $upstream_response_time - $request_time';
5156

5257
# send logs to STDOUT so they can be seen using 'docker logs'
5358
access_log /opt/nginx/logs/access.log upstreaminfo;
@@ -82,7 +87,11 @@ http {
8287
{{ if eq $useFirewall "true" }}include /opt/nginx/firewall/active-mode.rules;{{ end }}
8388
proxy_buffering off;
8489
proxy_set_header Host $host;
90+
{{ if ne $useProxyProtocol "false" }}
91+
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
92+
{{ else }}
8593
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
94+
{{ end }}
8695
proxy_redirect off;
8796
proxy_connect_timeout {{ or (.deis_router_controller_timeout_connect) "10s" }};
8897
proxy_send_timeout {{ or (.deis_router_controller_timeout_send) "20m" }};
@@ -126,7 +135,11 @@ http {
126135
{{ if eq $useFirewall "true" }}include /opt/nginx/firewall/active-mode.rules;{{ end }}
127136
proxy_buffering off;
128137
proxy_set_header Host $host;
138+
{{ if ne $useProxyProtocol "false" }}
139+
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
140+
{{ else }}
129141
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
142+
{{ end }}
130143
proxy_redirect off;
131144
proxy_connect_timeout 10s;
132145
proxy_send_timeout {{ $defaultTimeout }}s;
@@ -168,8 +181,8 @@ http {
168181
{{ if index $root (printf "deis_certs_%s_cert" (Replace (Base $domain.Key) "-" "_" -1)) }}
169182
server_name_in_redirect off;
170183
port_in_redirect off;
171-
listen 80;
172-
listen 443 ssl spdy;
184+
listen 80{{ if ne $useProxyProtocol "false" }} proxy_protocol{{ end }};
185+
listen 443 ssl spdy{{ if ne $useProxyProtocol "false" }} proxy_protocol{{ end }};
173186
ssl_certificate /etc/ssl/deis/certs/{{ Base $domain.Key }}.cert;
174187
ssl_certificate_key /etc/ssl/deis/keys/{{ Base $domain.Key }}.key;
175188
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
@@ -194,7 +207,11 @@ http {
194207
}
195208
proxy_set_header X-Forwarded-Port $access_port;
196209
proxy_set_header X-Forwarded-Proto $access_scheme;
210+
{{ if ne $useProxyProtocol "false" }}
211+
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
212+
{{ else }}
197213
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
214+
{{ end }}
198215
proxy_set_header X-Forwarded-Ssl $access_ssl;
199216
proxy_redirect off;
200217
proxy_connect_timeout 30s;
@@ -244,7 +261,11 @@ http {
244261
}
245262
proxy_set_header X-Forwarded-Port $access_port;
246263
proxy_set_header X-Forwarded-Proto $access_scheme;
264+
{{ if ne $useProxyProtocol "false" }}
265+
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
266+
{{ else }}
247267
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
268+
{{ end }}
248269
proxy_set_header X-Forwarded-Ssl $access_ssl;
249270
proxy_redirect off;
250271
proxy_connect_timeout 30s;
@@ -278,7 +299,7 @@ http {
278299

279300
# healthcheck
280301
server {
281-
listen 80 default_server;
302+
listen 80 default_server{{ if .deis_router_proxyProtocol }} proxy_protocol{{ end }};
282303
location /health-check {
283304
default_type 'text/plain';
284305
access_log off;

0 commit comments

Comments
 (0)