Reverse proxy an apache who forces ssl

Hi,

I am trying to proxy an apache, who forces ssl, see my vhost config:

RewriteEngine On
RewriteRule /(.*)$ https://www.acme.eu/$1 [R=301,L]

The nginx config for port 443 looks like this:

[…]
location ~* .(jpg|gif|png|css|js) {
try_files $uri @proxy;
}
location @proxy {
proxy_pass http://www.acme.eu;
}
location / {
proxy_pass http://www.acme.eu;
}

This obviously gives me a rewrite loop, since apache forces https, and
nginx keeps trying http.
When I change http to https in the location blocks, I get a 502 bad
gateway error, and the nginx log tells me

012/07/17 15:42:30 [error] 3671#0: *21 SSL_do_handshake() failed (SSL:
error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol)
while SSL handshaking to upstream, client: 8.1.87.11, server:
www.acme.eu, request: “GET / HTTP/1.1”, upstream:
https://10.11.12.13:443/”, host: “www.acme.eu”

My interpretation is that nginx does not know how to handle the upstream
ssl connection. Is that correct?
How can I configure nginx to do that? Is that possible at all?

Not sure if its of interest, but: nginx has the ssl certs for
www.acme.eu configured correctly, but thats for the side where nginx is
the server to the client.
Of course, an option would be to drop the https forcing in the apache,
and put the forcing in nginx, but currently that is not an option, as we
are in a testing phase, where the proxied and unproxied versions of the
site must be available.

Isaac

You can use ‘https’ in proxy pass eg:

location @proxy {
proxy_pass https://www.acme.eu;
}

If you define your backends via upstream {} add also :443 port there.

It is kinda overhead to talk to backends via SSL but it’s possible.

rr

On 07/17/2012 04:17 PM, Reinis R. wrote:

You can use ‘https’ in proxy pass eg:

location @proxy {
proxy_pass https://www.acme.eu;
}

If you define your backends via upstream {} add also :443 port there.
I defined my upstream like this:
upstream backend-secure {
server 10.10.2.1:443 max_fails=20;
server 10.10.2.1:443 max_fails=20;
}
and my proxy pass
location ~* .(jpg|gif|png|css|js) {
try_files $uri @proxy;
}
location @proxy {
proxy_pass https://backend-secure;
}
location / {
proxy_pass https://backend-secure;
}

but I keep getting the 502 Bad Gateway error, and

2012/07/17 18:40:05 [error] 5043#0: *1 SSL_do_handshake() failed (SSL:
error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol)
while SSL handshaking to upstream, client: 8.12.87.11, server:
www.acme.eu, request: “GET / HTTP/1.1”, upstream:
https://10.10.2.1:443/”, host: “www.acme.eu”

in my log. What am I doing wrong?

It is kinda overhead to talk to backends via SSL
I know, I won’t use it in production, but at the moment I need this.

Isaac

2012/07/17 18:40:05 [error] 5043#0: *1 SSL_do_handshake() failed (SSL:
error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol)
while SSL handshaking to upstream, client: 8.12.87.11, server:
www.acme.eu, request: “GET / HTTP/1.1”, upstream:
https://10.10.2.1:443/”, host: “www.acme.eu”

in my log. What am I doing wrong?

The error is kinda saying that the upstream is not talking SSL (or vice
versa if I’m wrong).

Can you show what does this return ( change the 10.10.2.1 to your
backend
apache ip/host if its not the real one from the error message):

openssl s_client -connect 10.10.2.1:443

It will either return the SSL cert information (then the backend is fine
and
the problem is on nginx side) or the same error.

rr

On 07/17/2012 07:29 PM, Reinis R. wrote:

Can you show what does this return ( change the 10.10.2.1 to your
backend apache ip/host if its not the real one from the error message):

openssl s_client -connect 10.10.2.1:443
Its the same error as with nginx:
~# openssl s_client -connect 10.10.2.1:443
CONNECTED(00000003)
7571:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown
protocol:s23_clnt.c:607:

It will either return the SSL cert information (then the backend is fine
and the problem is on nginx side) or the same error.
This would imply that the problem is on the backend (the apache) side.
But: I can connect to the backend directly (not via nginx) using https
without any problem. So I am not sure about this conclusion.
Hm, it might still be a problem with the backend, but its not that ssl
is not working in general on the backend.

Any hints are appreciated :slight_smile:

Isaac

hi all ,
I’m getting the same , my upstream https servers requires client
authenication (ie authenicate who nginx is!!) but this fails, yet when
i verfied the same using wget alls okay … btw i using self sign
certs for now

I get the a 502 bad gateway too … does nginx support this
configuration or have i messed up my ssl configuration

thanks
saucepan

Posted at Nginx Forum:

Hi all, here some further info on the issue, from my investigation into
2-way ssl support to upstream servers , i gathered the following ssl out
form my upstream server . You can see the problem occurs after the
server handshake the certificate chain is not found for nginx
*** Certificate chain


and for wget its this:

*** Certificate chain
chain [0] = [
[
Version: V3
Subject: CN=blahblahblah, OU=Eng, O=saucepan, L=Dublin, ST=Dublin,
C=IE
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

Here the full output if your really interested

heres the the nginx → upstream server:


*** Diffie-Hellman ServerKeyExchange
DH Modulus: { 233, 230, 66, 89, 157, 53, 95, 55, 201, 127, 253, 53,
103, 18, 11, 142, 37, 201, 205, 67, 233, 39, 179, 169, 103, 15, 190,
197, 216, 144, 20, 25, 34, 210, 195, 179, 173, 36, 128, 9, 55, 153, 134,
157, 30, 132, 106, 171, 73, 250, 176, 173, 38, 210, 206, 106, 34, 33,
157, 71, 11, 206, 125, 119, 125, 74, 33, 251, 233, 194, 112, 181, 127,
96, 112, 2, 243, 206, 248, 57, 54, 148, 207, 69, 238, 54, 136, 193, 26,
140, 86, 171, 18, 122, 61, 175 }
DH Base: { 48, 71, 10, 213, 160, 5, 251, 20, 206, 45, 157, 205, 135,
227, 139, 199, 209, 177, 197, 250, 203, 174, 203, 233, 95, 25, 10, 167,
163, 29, 35, 196, 219, 188, 190, 6, 23, 69, 68, 64, 26, 91, 44, 2, 9,
101, 216, 194, 189, 33, 113, 211, 102, 132, 69, 119, 31, 116, 186, 8,
77, 32, 41, 216, 60, 28, 21, 133, 71, 243, 169, 241, 162, 113, 91, 226,
61, 81, 174, 77, 62, 90, 31, 106, 112, 100, 243, 22, 147, 58, 52, 109,
63, 82, 146, 82 }
Server DH Public Key: { 192, 133, 229, 57, 195, 243, 75, 86, 165, 34,
255, 75, 168, 125, 4, 223, 163, 159, 72, 6, 224, 226, 64, 12, 249, 195,
253, 39, 103, 164, 9, 200, 183, 199, 121, 52, 79, 122, 190, 88, 32, 5,
95, 70, 16, 151, 58, 64, 174, 208, 177, 123, 213, 92, 45, 234, 189, 61,
124, 82, 253, 91, 100, 247, 214, 162, 95, 161, 65, 53, 167, 151, 18, 7,
177, 98, 155, 97, 150, 26, 77, 37, 243, 165, 134, 150, 135, 6, 105, 76,
47, 104, 184, 128, 224, 225 }
Signed with a DSA or RSA public key
*** CertificateRequest
Cert Types: RSA, DSS
Cert Authorities:
<CN=blahblahblah, OU=Eng, O=saucepan, L=Dublin, ST=Dublin, C=IE>
*** ServerHelloDone
qtp1771121238-29, WRITE: TLSv1 Handshake, length = 1460
qtp1771121238-27, READ: TLSv1 Handshake, length = 7
*** Certificate chain


qtp1771121238-27, fatal error: 42: null cert chain
javax.net.ssl.SSLHandshakeException: null cert chain
qtp1771121238-27, SEND TLSv1 ALERT: fatal, description =
bad_certificate
qtp1771121238-27, WRITE: TLSv1 Alert, length = 2
qtp1771121238-27, fatal: engine already closed. Rethrowing
javax.net.ssl.SSLHandshakeException: null cert chain
qtp1771121238-27, called closeOutbound()
qtp1771121238-27, closeOutboundInternal()

Now here the output of the server with wget … lots of 64 bit encoding
that can be ingored… just left it in so peeps can see


*** Diffie-Hellman ServerKeyExchange
DH Modulus: { 233, 230, 66, 89, 157, 53, 95, 55, 201, 127, 253, 53,
103, 18, 11, 142, 37, 201, 205, 67, 233, 39, 179, 169, 103, 15, 190,
197, 216, 144, 20, 25, 34, 210, 195, 179, 173, 36, 128, 9, 55, 153, 134,
157, 30, 132, 106, 171, 73, 250, 176, 173, 38, 210, 206, 106, 34, 33,
157, 71, 11, 206, 125, 119, 125, 74, 33, 251, 233, 194, 112, 181, 127,
96, 112, 2, 243, 206, 248, 57, 54, 148, 207, 69, 238, 54, 136, 193, 26,
140, 86, 171, 18, 122, 61, 175 }
DH Base: { 48, 71, 10, 213, 160, 5, 251, 20, 206, 45, 157, 205, 135,
227, 139, 199, 209, 177, 197, 250, 203, 174, 203, 233, 95, 25, 10, 167,
163, 29, 35, 196, 219, 188, 190, 6, 23, 69, 68, 64, 26, 91, 44, 2, 9,
101, 216, 194, 189, 33, 113, 211, 102, 132, 69, 119, 31, 116, 186, 8,
77, 32, 41, 216, 60, 28, 21, 133, 71, 243, 169, 241, 162, 113, 91, 226,
61, 81, 174, 77, 62, 90, 31, 106, 112, 100, 243, 22, 147, 58, 52, 109,
63, 82, 146, 82 }
Server DH Public Key: { 102, 235, 160, 161, 240, 122, 53, 136, 76, 193,
131, 131, 190, 93, 10, 140, 187, 203, 66, 141, 87, 65, 192, 213, 28, 61,
192, 175, 244, 8, 195, 84, 143, 84, 82, 15, 251, 235, 25, 168, 121, 27,
95, 64, 38, 254, 2, 153, 147, 111, 33, 74, 29, 40, 176, 27, 11, 60, 61,
102, 91, 42, 156, 69, 245, 73, 18, 173, 24, 64, 32, 14, 216, 56, 95,
177, 244, 158, 253, 188, 22, 181, 148, 134, 142, 89, 87, 99, 236, 117,
93, 115, 3, 223, 188, 156 }
Signed with a DSA or RSA public key
*** CertificateRequest
Cert Types: RSA, DSS
Cert Authorities:
<CN=blahblahblah, OU=Eng, O=saucepan, L=Dublin, ST=Dublin, C=IE>
*** ServerHelloDone
qtp1771121238-30, WRITE: SSLv3 Handshake, length = 1460
qtp1771121238-29, READ: SSLv3 Handshake, length = 798
*** Certificate chain
chain [0] = [
[
Version: V3
Subject: CN=blahblahblah, OU=Eng, O=saucepan, L=Dublin, ST=Dublin,
C=IE
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

Key: Sun RSA public key, 1024 bits
modulus:
127587979862584476706861530103335113586892890796380145018891142016239072352217188124779733934530261425464442718644103381320330433922989773276207747427016139967623107463854944049930411583732215014902035974735609136593060832687281722217241269155671154565182857904746107818762911813662092673804966355501353550911
public exponent: 65537
Validity: [From: Tue Jul 17 17:19:00 IST 2012,
To: Thu Jul 10 17:19:00 IST 2042]
Issuer: CN=blahblahblah, OU=Eng, O=saucepan, L=Dublin, ST=Dublin,
C=IE
SerialNumber: [ d11ba577 66877914]

Certificate Extensions: 3
[1]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: AE 98 C6 7D 02 2D 40 AB 60 BA 46 E0 E0 2F D0 33
…-@.`.F…/.3
0010: 29 CC 9D 02 )…
]
]

[2]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: AE 98 C6 7D 02 2D 40 AB 60 BA 46 E0 E0 2F D0 33
…-@.`.F…/.3
0010: 29 CC 9D 02 )…
]

[CN=blahblahblah, OU=Eng, O=saucepan, L=Dublin, ST=Dublin, C=IE]
SerialNumber: [ d11ba577 66877914]
]

[3]: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
CA:true
PathLen:2147483647
]

]
Algorithm: [SHA1withRSA]
Signature:
0000: 13 50 00 91 E6 DA 55 B7 C0 F8 C6 A7 77 A4 85 08
.P…U…w…
0010: D2 BB DB 32 79 E9 C4 D1 C9 67 7C 16 F4 52 EC EC
…2y…g…R…
0020: CD B9 EC 79 94 6B 4E 79 5B 2F A0 D8 D2 91 F8 98
…y.kNy[/…
0030: 6E 19 3D 5C 0F B4 37 FC 8A 03 CC 72 C3 0D 54 97
n.=..7…r…T.
0040: B4 9E D7 A8 6C EE 42 CB B7 12 DF FA AE 50 BB DA
…l.B…P…
0050: 66 DC 0B 87 AD 88 EE 35 51 45 5E 89 3D 05 03 1E
f…5QE^.=…
0060: E8 04 75 D2 F5 DF F7 7C 3A C8 77 9B C7 D0 FE 6E
…u…:.w…n
0070: 0D 29 FE 4B 84 75 56 21 45 C2 8F 2B 2D A0 90 3F
.).K.uV!E…±…?

]


Found trusted certificate:
[
[
Version: V3
Subject: CN=blahblahblah, OU=Eng, O=saucepan, L=Dublin, ST=Dublin,
C=IE
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

Key: Sun RSA public key, 1024 bits
modulus:
127587979862584476706861530103335113586892890796380145018891142016239072352217188124779733934530261425464442718644103381320330433922989773276207747427016139967623107463854944049930411583732215014902035974735609136593060832687281722217241269155671154565182857904746107818762911813662092673804966355501353550911
public exponent: 65537
Validity: [From: Tue Jul 17 17:19:00 IST 2012,
To: Thu Jul 10 17:19:00 IST 2042]
Issuer: CN=blahblahblah, OU=Eng, O=saucepan, L=Dublin, ST=Dublin,
C=IE
SerialNumber: [ d11ba577 66877914]

Certificate Extensions: 3
[1]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: AE 98 C6 7D 02 2D 40 AB 60 BA 46 E0 E0 2F D0 33
…-@.`.F…/.3
0010: 29 CC 9D 02 )…
]
]

[2]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: AE 98 C6 7D 02 2D 40 AB 60 BA 46 E0 E0 2F D0 33
…-@.`.F…/.3
0010: 29 CC 9D 02 )…
]

[CN=blahblahblah, OU=Eng, O=saucepan, L=Dublin, ST=Dublin, C=IE]
SerialNumber: [ d11ba577 66877914]
]

[3]: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
CA:true
PathLen:2147483647
]

]
Algorithm: [SHA1withRSA]
Signature:
0000: 13 50 00 91 E6 DA 55 B7 C0 F8 C6 A7 77 A4 85 08
.P…U…w…
0010: D2 BB DB 32 79 E9 C4 D1 C9 67 7C 16 F4 52 EC EC
…2y…g…R…
0020: CD B9 EC 79 94 6B 4E 79 5B 2F A0 D8 D2 91 F8 98
…y.kNy[/…
0030: 6E 19 3D 5C 0F B4 37 FC 8A 03 CC 72 C3 0D 54 97
n.=..7…r…T.
0040: B4 9E D7 A8 6C EE 42 CB B7 12 DF FA AE 50 BB DA
…l.B…P…
0050: 66 DC 0B 87 AD 88 EE 35 51 45 5E 89 3D 05 03 1E
f…5QE^.=…
0060: E8 04 75 D2 F5 DF F7 7C 3A C8 77 9B C7 D0 FE 6E
…u…:.w…n
0070: 0D 29 FE 4B 84 75 56 21 45 C2 8F 2B 2D A0 90 3F
.).K.uV!E…±…?

]
qtp1771121238-29, READ: SSLv3 Handshake, length = 102
*** ClientKeyExchange, DH
DH Public key: { 80, 96, 106, 59, 53, 100, 40, 243, 147, 137, 5, 149,
205, 218, 3, 16, 189, 80, 152, 47, 53, 34, 215, 202, 129, 236, 87, 89,
115, 239, 155, 183, 242, 83, 80, 66, 60, 78, 13, 1, 132, 141, 26, 135,
74, 19, 50, 137, 202, 177, 60, 8, 43, 92, 139, 15, 111, 166, 6, 128,
192, 161, 4, 153, 21, 180, 135, 62, 63, 53, 194, 155, 152, 152, 180, 13,
83, 69, 121, 223, 113, 130, 34, 93, 127, 66, 40, 102, 25, 219, 155, 175,
85, 218, 80, 192 }
SESSION KEYGEN:
PreMaster Secret:
0000: CA 5B 14 8F 70 CD 6F 59 99 E3 FD 66 80 F3 2B C1
.[…p.oY…f…+.
0010: 3A 0A 50 F3 D1 78 1B C9 0C DD 71 4D 9A 06 1C A1
:.P…x…qM…
0020: 42 8F 19 BB F4 7C CA A9 2C F7 03 13 1F 15 D7 94
B…,…
0030: 6C D3 65 38 FC E9 D1 73 85 AE 2E A1 91 A4 14 9B
l.e8…s…
0040: 1D AB 2C 92 6C 7C 68 DA 3B 52 66 2C 27 03 59 FA
…,.l.h.;Rf,‘.Y.
0050: 47 DA 5F 9C 24 D9 DF DB 4D E5 C2 0B A4 74 DF 95
G._.$…M…t…
CONNECTION KEYGEN:
Client Nonce:
0000: 50 05 94 18 D2 E7 F9 72 61 2D CB 12 39 83 68 6D
P…ra-…9.hm
0010: 7F F7 82 5E E1 6E 42 C1 A7 03 0C 70 34 A5 EC 61
…^.nB…p4…a
Server Nonce:
0000: 50 05 94 19 FB FC F7 A0 D3 CF BD 05 A1 68 34 C7
P…h4.
0010: 42 EA 30 D0 29 8B FF 21 90 2A BA FC 4F 27 FB 6A
B.0.)…!.*…O’.j
Master Secret:
0000: 3A CF 9C E8 39 80 CD 83 07 B9 A7 37 B4 A5 81 A3
:…9…7…
0010: 6B 14 E5 E1 A2 8A C4 B1 AC 25 C6 11 80 E1 F4 A1
k…%…
0020: AE D2 A2 B1 B7 15 94 A2 93 6B 57 95 98 F8 A5 D3
…kW…
Client MAC write Secret:
0000: 4F 54 22 42 6B 2F 1F 33 09 EE 51 D6 4E F2 D1 CC
OT"Bk/.3…Q.N…
0010: DC D8 C8 C7 …
Server MAC write Secret:
0000: 10 0D E5 5D 55 DE 48 67 39 1F B4 E9 16 4A D2 D5
…]U.Hg9…J…
0010: D3 2C 82 4A .,.J
Client write key:
0000: AA 82 DC 16 D8 B0 7B D6 F6 6E 20 4E BB B6 65 0A …n
N…e.
0010: 73 FE 55 E4 9D 8B 4E 21 s.U…N!
Server write key:
0000: 4D B9 87 00 5A 1E F6 92 C4 89 36 86 7F DB B2 14
M…Z…6…
0010: D8 B7 1C 00 30 16 7E CA …0…
Client write IV:
0000: 6E D0 C8 54 5C 0F 07 81 n…T.…
Server write IV:
0000: 31 E6 B6 70 4C 78 93 A6 1…pLx…
qtp1771121238-29, READ: SSLv3 Handshake, length = 134
*** CertificateVerify
qtp1771121238-29, READ: SSLv3 Change Cipher Spec, length = 1
qtp1771121238-29, READ: SSLv3 Handshake, length = 64
*** Finished
verify_data: { 185, 100, 131, 53, 152, 57, 153, 230, 137, 226, 218,
237, 18, 131, 144, 8, 163, 43, 99, 82, 149, 131, 123, 251, 14, 211, 158,
109, 43, 103, 80, 47, 44, 101, 221, 197 }


qtp1771121238-29, WRITE: SSLv3 Change Cipher Spec, length = 1
*** Finished
verify_data: { 226, 10, 167, 159, 75, 91, 46, 203, 145, 224, 225, 64,
174, 171, 207, 1, 122, 104, 232, 72, 193, 222, 162, 51, 124, 234, 143,
246, 134, 208, 115, 240, 209, 174, 1, 192 }


qtp1771121238-29, WRITE: SSLv3 Handshake, length = 64
%% Cached server session: [Session-1, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA]

Posted at Nginx Forum:

On 07/18/2012 11:46 AM, Reinis R. wrote:

It’s the problem on backend then - it doesn’t (want to) talk ssl, at
least on that particular IP/port.
Yes, that was the problem. The apache was configured to speak https on
port 45600. So I changed my backend definition acordingly, and things
worked!

Thank you very much for your guidance!

Not directly related, but just for the record:
The site contains a login, which needed a
proxy_set_header Host $host;
in the location section with the proxy_pass in order to work.

If you test with browser it might (out of thin air) not complain about
the site not actually being SSL or the apache does some sort of redirect
before actually landing on the real SSL (virtual)host.
Yes, there is a loadbalancer, which did the port changing bevore the
request came to apache.

Isaac

Hello!

On Tue, Jul 17, 2012 at 01:30:06PM -0400, saucepan wrote:

hi all ,
I’m getting the same , my upstream https servers requires client
authenication (ie authenicate who nginx is!!) but this fails, yet when
i verfied the same using wget alls okay … btw i using self sign
certs for now

I get the a 502 bad gateway too … does nginx support this
configuration or have i messed up my ssl configuration

nginx doesn’t currently support client certificate authentication
to upstream https servers.

Maxim D.

openssl s_client -connect 10.10.2.1:443
Its the same error as with nginx:
~# openssl s_client -connect 10.10.2.1:443
CONNECTED(00000003)
7571:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown
protocol:s23_clnt.c:607:

It’s the problem on backend then - it doesn’t (want to) talk ssl, at
least on that particular IP/port.

But: I can connect to the backend directly (not via nginx) using https without
any problem. So I am not sure about this
conclusion.

Can you show what does this return: wget --no-check-certificate -S
–spider https://10.10.2.1

If you test with browser it might (out of thin air) not complain about
the site not actually being SSL or the apache does some sort
of redirect before actually landing on the real SSL (virtual)host.

But overall you should probably show your apache config (the parts with
‘SSLEngine on’ ).

rr