NGINX SSL Reverse Proxy Verifikasi Upstream SSL
Saya memiliki pengaturan NGINX sebagai proxy terbalik untuk meng-host beberapa situs web hanya dengan menggunakan satu alamat IP. Saya memiliki sertifikat Lets Encrypt di proxy dan sertifikat Lets Encrypt yang berbeda di server upstream. Pada dasarnya, saya memerlukan NGINX untuk meneruskan lalu lintas ke server hulu dan memverifikasi bahwa server hulu memiliki sertifikat TLS yang valid. Jika saya menonaktifkan proxy_ssl_verify
, itu akan berhasil. Jika saya masuk ke https://app.local.example.com
jaringan internal saya, aplikasi berfungsi dengan baik.
Diagram jaringan:
https://app.example.com --> NGINX Reverse Proxy --> https://app.local.example.com (Local IP Address)
File Konfigurasi Proxy Terbalik NGINX:
server {
listen 80;
rewrite ^ https://$host$request_uri? permanent;
}
server {
server_name app.example.com;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/app.example.com/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/app.example.com/chain.pem;
location / {
proxy_redirect off;
proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Ssl on; proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-HTTPS on;
proxy_ssl_session_reuse off;
proxy_ssl_name app.local.example.com
proxy_ssl_verify on;
proxy_ssl_verify_depth 2; # I've tried 1,2,3,4
proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
proxy_pass https://app.local.example.com
}
}
Inilah pesan kesalahan yang saya dapatkan.
[error] 1087#1087: *2 upstream SSL certificate verify error: (20:unable to get local issuer certificate) while SSL handshaking to upstream, client: [Client IP], server: app.example.com, request: "GET / HTTP/1.1", upstream: "https://192.168.1.5:443/", host: "app.local.example.com", referrer: "https://app.example.com/">
Versi OpenSSL: OpenSSL 1.1.1f 31 Mar 2020
nginx -v: nginx version: nginx/1.18.0 (Ubuntu)
kucing / etc / issue: Ubuntu 20.04.1 LTS \n \l
Output dari openssl s_client -connect app.local.example.com:443
CONNECTED(00000003)
depth=0 CN = app.local.example.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = app.local.example.com
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:CN = app.local.example.com
i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFeDCCBGCgAwIBAgISA8NkbZ6wz2EnKcedXujKT9AmMA0GCSqGSIb3DQEBCwUA
...
-----END CERTIFICATE-----
...
SSL-Session:
Protocol : TLSv1.3
...
Verify return code: 21 (unable to verify the first certificate)
Jawaban
Certificate chain
0 s:CN = app.local.example.com
i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
Server Anda tidak dikonfigurasi dengan benar. Alih-alih mengirim sertifikat daun (app.local.example.com) dan sertifikat perantara, ia hanya mengirim sertifikat daun. Karena sertifikat perantara hilang, tidak ada jalur kepercayaan yang dapat dibuat ke jangkar kepercayaan lokal, yang berarti validasi sertifikat gagal dengan "tidak bisa mendapatkan sertifikat penerbit lokal" . Browser sering kali mengatasi masalah seperti itu dengan mendapatkan sertifikat perantara yang hilang dari tempat lain, tetapi tumpukan TLS lain biasanya tidak melakukan penyelesaian seperti itu.
Setelah Anda mengkonfigurasi server dengan benar, Anda akan melihat yang berikut ini di openssl s_client
. Setelah ini selesai, nginx juga akan berfungsi.
Certificate chain
0 s:CN = app.local.example.com
i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
i:O = Digital Signature Trust Co., CN = DST Root CA X3
Saya mengubah ssl_certificate
nilai dari cert.pem
menjadi fullchain.pem
di server hulu.
ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/app.example.com/chain.pem;
Berikut tautan ke file konfigurasi NGINX yang saya gunakan