2011-06-13 16 views
14

के तहत मैं nginx में चल रहे एक सिनात्रा एप्लिकेशन है, कैसे ठीक करने के लिए (के रूप में पतली का उपयोग कर एक बैक-प्रॉक्सी) और मैं सिनात्रा में redirect '/<path>' बयान उपयोग कर रहा हूँ। हालांकि, जब मैं https के अंतर्गत साइट तक पहुंचता हूं, तो वे रीडायरेक्ट मुझे के बजाय http://localhost/<path> पर भेजते हैं।सिनात्रा http के लिए https पुनः निर्देशित nginx

वर्तमान में, nginx नियंत्रण इस आदेश proxy_pass http://thin _cluster के साथ पतली करने के लिए, गुजरता है जहां thin_cluster

upstream thin_cluster { server unix:/tmp/thin.cct.0.sock; } 

है मैं इसे ठीक कर सकते हैं कैसे?

+0

जोड़ने 'proxy_set_header X-Forwarded-आद्य $ योजना है;' अपने 'proxy_pass' लाइन मदद के बाद? – matt

+0

आपको इसे एक उत्तर के रूप में लिखना चाहिए ... यह मेरी समस्या को ठीक करता है। धन्यवाद! –

उत्तर

22

आदेश सिनात्रा सही ढंग से रीडायरेक्ट के लिए इस्तेमाल किया यूआरएल इकट्ठा करने के लिए के लिए में भी है करने के लिए अच्छा है, यह करने में सक्षम होने की जरूरत है यह निर्धारित करें कि अनुरोध एसएसएल का उपयोग कर रहा है, ताकि रीडायरेक्ट http या https का उपयोग उचित रूप से किया जा सके।

जाहिर है पतली करने के लिए वास्तविक कॉल SSL का उपयोग नहीं किया जाता है, के रूप में यह सामने अंत वेब सर्वर द्वारा संभाला जा रहा है, और उसे प्रॉक्सी अनुरोध स्पष्ट है। इसलिए हमें सिनात्रा को बताने का एक तरीका चाहिए कि इसे अनुरोध को सुरक्षित के रूप में देखना चाहिए, भले ही यह वास्तव में एसएसएल का उपयोग नहीं कर रहा हो।

आखिरकार वह कोड जो निर्धारित करता है कि अनुरोध को सुरक्षित के रूप में माना जाना चाहिए Rack::Request#ssl? और Rack::Request#scheme विधियों में है। scheme विधियों को देखने के लिए env हैश की जांच करता है कि कितने प्रविष्टियां मौजूद हैं। इनमें से एक HTTP_X_FORWARDED_PROTO है जो X-Forwarded-Proto HTTP शीर्षलेख से मेल खाता है। यदि यह सेट किया गया है, तो मान प्रोटोकॉल योजना (http या https) के रूप में उपयोग किया जाता है।

इसलिए यदि हम इस HTTP शीर्षलेख को अनुरोध पर जोड़ते हैं तो यह nginx से पीछे के अंत तक प्रॉक्सी हो जाता है, तो सिनात्रा सही ढंग से निर्धारित करने में सक्षम होगा कि https पर रीडायरेक्ट करना कब होगा। Nginx में हम proxy_set_header के साथ प्रॉक्सी अनुरोधों में हेडर जोड़ सकते हैं, और यह योजना $scheme variable में उपलब्ध है।

तो proxy_pass पंक्ति के बाद nginx विन्यास के लिए लाइन

proxy_set_header X-Forwarded-Proto $scheme; 

जोड़ने यह काम करना चाहिए।

+0

किसी कारण से यह मेरे शीर्षकों में होस्ट फ़ील्ड खराब कर दिया गया है, मेरे सभी रीडायरेक्ट_to को अमान्य डोमेन पर भेज रहा है। "Proxy_set_header होस्ट $ होस्ट" जोड़ना इसे ठीक किया गया। (मेरा ऐप एक उप-uri के तहत चल रहा है, और मुझे आश्चर्य है कि अगर एक मुद्दा है।) – bioneuralnet

+2

@bioneuralnet आप भी 'X-Forwarded-Host', जो' Host' हेडर की जाँच से पहले की जाँच करता रैक इस्तेमाल कर सकते हैं। मुझे लगता है कि nginx स्वचालित रूप से इन शीर्षकों को जोड़ता नहीं है, लेकिन अपाचे mod_proxy में करता है। – matt

+1

हाँ, मुझे लगता है कि यह भी काम करेगा। Http://wiki.nginx.org/HttpProxyModule#proxy_set_header पर एक दिलचस्प स्पष्टीकरण मिला।मैं अपने सभी ऐप्स के उपयोग के लिए http ब्लॉक में proxy_set_header होस्ट सेट कर रहा था। आपकी पोस्ट के आधार पर, मैंने स्थान @myapp में proxy_set_header एक्स-फॉरवर्ड-प्रोटो जोड़ा। दस्तावेज़ों के अनुसार, "उच्च स्तर पर जारी proxy_set_header निर्देश केवल विरासत में प्राप्त होते हैं जब किसी दिए गए स्तर पर कोई proxy_set_header निर्देश जारी नहीं किए जाते हैं।" तो @myapp में मेरा "स्थानीय" proxy_set_header कॉल मेरी "वैश्विक" proxy_set_header कॉल साफ़ कर रहा था, भले ही वे विभिन्न फ़ील्ड के लिए थे। – bioneuralnet

1

आप nginx परत में https पर जाने के लिए सभी लिंक मजबूर कर सकते हैं। nginx.conf में :

server{ 
    listen 80; 
    server_name example.com; 
    rewrite ^(.*) https://$server_name$1 redirect; 
}  

यह आश्वस्त करने के लिए कि आपके अनुरोधों हमेशा से रहे हैं https

+0

यह सहायक है ... लेकिन मुझसे पूछे गए प्रश्न का उत्तर नहीं देता है। यदि सर्वर HTTPS-only मोड में चल रहा है, तो मेरे पास पहले से ही यह कार्यक्षमता काम कर रही है; मेरी समस्या तब होती है जब मैं HTTPS और HTTP दोनों को स्वीकार करना चाहता हूं। –

संबंधित मुद्दे