এনগিনেক্সে, আমি কীভাবে সাব-ডোমেন রক্ষণাবেক্ষণের জন্য https- র সমস্ত HTTP অনুরোধগুলি পুনরায় লিখতে পারি?


508

আমি আমার ওয়েব সার্ভারে সমস্ত HTTP অনুরোধগুলি https অনুরোধ হিসাবে পুনরায় লিখতে চাই, আমি নিম্নলিখিতটি দিয়ে শুরু করেছি:

সার্ভার
    80 শুনুন;

    অবস্থান /
      পুনর্লিখন ^ (। *) https: //mysite.com$1 স্থায়ী;
    }
...


একটি সমস্যা হ'ল এটি কোনও সাবডোমেন তথ্য (যেমন, node1.mysite.com/folder) কে সরিয়ে দেয়, আমি কীভাবে উপরেরটি https এ পুনরায় লিখন করতে এবং সাব-ডোমেন বজায় রাখতে পারি?


2
দয়া করে 'গৃহীত উত্তর' সেরে সার্ভারফ্রন্ট /a/171238/90758 এ যাওয়ার বিষয়ে বিবেচনা করুন । এটাই সঠিক।
olafure

উত্তর:


748

এনগিনেক্সের নতুন সংস্করণগুলিতে সঠিক পদ্ধতি

এই প্রশ্নের আমার প্রথম উত্তরটি নির্দিষ্ট সময়ে সঠিক ছিল তা দেখাও, তবে এটি অন্য এক জটিলতায় পরিণত হয়েছিল - আপ টু ডেট থাকার জন্য দয়া করে পুনর্লিখনের ট্যাক্সিং ট্যাক্সগুলি পরীক্ষা করে দেখুন

আমি অনেক এসই ব্যবহারকারী দ্বারা সংশোধন করা হয়েছে, তাই ক্রেডিট তাদের যায়, কিন্তু আরও গুরুত্বপূর্ণ, এখানে সঠিক কোড:

server {
       listen         80;
       server_name    my.domain.com;
       return         301 https://$server_name$request_uri;
}

server {
       listen         443 ssl;
       server_name    my.domain.com;
       # add Strict-Transport-Security to prevent man in the middle attacks
       add_header Strict-Transport-Security "max-age=31536000" always; 

       [....]
}

3
আপনি ডোমেন ভিত্তিতে একটি ডোমেনে এটি করতে হবে তবে - না? আপনি যদি এটি আপনার সার্ভারের প্রতিটি ডোমেনে প্রয়োগ করতে চান?
জেএম 4

30
@ জেএম 4: আপনি যদি সার্ভার_নামের পরিবর্তে পুনরায় লেখায় $ হোস্ট use ব্যবহার করেন এবং শ্রবণ নির্দেশিকায় ডিফল্ট_সার্ভার যোগ করেন এটি আপনার সার্ভারের প্রতিটি ডোমেনের জন্য কাজ করবে।
ক্লাস ভ্যান শেলভেন

5
এটি উল্লেখ করা গুরুত্বপূর্ণ যে 301 সমাপ্তির তারিখ ছাড়াই আপনার স্থানীয় ক্যাশে সঞ্চিত রয়েছে। কনফিগারেশন পরিবর্তনগুলি খুব কার্যকর নয়
ট্রেফেক্স

9
@Everone পোষ্ট সামগ্রী সংরক্ষণের জন্য 307 পুনর্নির্দেশ ব্যবহার করুন।
মাহমুদ আল-কুদসী

10
মনে রাখবেন আপনি সাবডোমেন ব্যবহার করছেন তার $hostপরিবর্তে আপনাকে অবশ্যই ব্যবহার করা উচিত $server_name
ক্যাটফিশ

276

দ্রষ্টব্য: এটি করার সর্বোত্তম উপায়টি https://serverfault.com/a/401632/3641 দ্বারা সরবরাহ করা হয়েছিল - তবে এখানে পুনরাবৃত্তি করা হয়েছে:

server {
    listen         80;
    return 301 https://$host$request_uri;
}

সহজতম ক্ষেত্রে আপনার হোস্টটি আপনার পরিষেবা হিসাবে স্থির হয়ে যাবে আপনি তাদের এ পাঠাতে চান - এটি ব্রাউজারে 301 পুনর্নির্দেশ করবে এবং ব্রাউজারের ইউআরএল সেই অনুযায়ী আপডেট হবে।

নীচে পূর্বের উত্তরটি দেওয়া হয়েছে, যা রেইগেক্সের কারণে অকার্যকর, @ কেমিন্ডি দেখায় একটি সাধারণ 301 দুর্দান্ত

আমি 0.8.39 এবং তার বেশি উপরে এনজিনেক্স ব্যবহার করেছি এবং নিম্নলিখিতগুলি ব্যবহার করেছি:

 server {
       listen 80;
       rewrite ^(.*) https://$host$1 permanent;
 }

ক্লায়েন্টের স্থায়ী পুনঃনির্দেশ প্রেরণ করে।


15
আমি মনে করি এটি 80 হওয়া উচিত - যেহেতু এটি HTTP শুনছে এবং তারপরে ক্লায়েন্টকে https (443) হিসাবে ফিরে আসতে বলছে।
মাইকেল নেল

3
এটি শীর্ষ উত্তর হতে হবে!
নাথান

3
এটি সর্বাধিক করের উত্তর।
কেস

1
এটি সবচেয়ে সহজ, তবে স্বল্পতম সুরক্ষিত - আপনি আপনার সার্ভারে এটি ব্যবহার করার অনুমতি দিচ্ছেন কিনা তা পরীক্ষা না করেই আপনার সার্ভারটি কোনও ব্যবহারকারীকে কোনও পৃষ্ঠাতে পুনর্নির্দেশের অনুমতি দেয়। যদি আপনার সার্ভারটি মাইডোমেন.কমকে পরিবেশন করে তবে ক্ষতিকারক ব্যবহারকারীরা এখনও মাইডোমেন.কম, যেমন গুগল.কমের মতো অন্যান্য ডোমেনে ব্যবহারকারীদের পুনর্নির্দেশ করতে আপনার সার্ভারটি ব্যবহার করতে পারেন।
ফ্রেডকিউই

10
@ ক্যাবলেট এখানে কোনও সুরক্ষা সমস্যা নেই। পুনর্নির্দেশ পরিবেশন করা কোনও সুরক্ষা ঝুঁকি নিয়ে আসে না। অ্যাক্সেস নিয়ন্ত্রণের প্রয়োজনীয়তাগুলি থাকলে, সেগুলি ব্রাউজারটি নতুন ইউআরএলকে অনুরোধ করে সেই স্থানে পরীক্ষা করা উচিত। পুনর্নির্দেশের ভিত্তিতে ব্রাউজারটি অ্যাক্সেস অর্জন করবে না বা নতুন ইউআরএলের অনুরোধ করতে তাদের পুনঃনির্দেশের প্রয়োজন হবে না।
mc0e

125

আমি মনে করি সেরা এবং একমাত্র উপায়টি এইচটিটিপি 301 স্থানান্তরিত স্থায়ীভাবে পুনঃনির্দেশের মতো ব্যবহার করা উচিত :

server {
    listen         [::]:80;
    return 301 https://$host$request_uri;
}

HTTP- র 301 স্থায়ীভাবে স্থানান্তরিত পুনর্নির্দেশ এছাড়াও সবচেয়ে বেশি কার্যকরী কোন Regex মূল্যায়ন করা হয়, কারণ, ইতিমধ্যে উল্লেখ অনুযায়ী pitfails


নতুন এইচটিটিপি 308 স্থানান্তরিত স্থায়ীভাবে অনুরোধের পদ্ধতিটি সংরক্ষণ করে এবং বড় ব্রাউজারগুলি দ্বারা সমর্থিত । উদাহরণস্বরূপ, ব্যবহার 308প্রতিরোধ থেকে অনুরোধ পদ্ধতি পরিবর্তন করা থেকে ব্রাউজার POSTথেকে GETপুনর্নির্দেশ অনুরোধের জন্য।


আপনি যদি হোস্টনাম এবং সাবডোমেন সংরক্ষণ করতে চান তবে এই উপায়।

আপনার ডিএনএস না থাকলে এটি এখনও কাজ করে , যেমন আমি স্থানীয়ভাবে এটি ব্যবহার করছি। আমি উদাহরণস্বরূপ অনুরোধ করছি http://192.168.0.100/index.phpএবং এর সাথে হুবহু পুনঃনির্দেশিত হব https://192.168.0.100/index.php

আমি listen [::]:80আমার হোস্টটিতে ব্যবহার করি কারণ আমি bindv6onlyসেট করে রেখেছি false, সুতরাং এটি আইপিভি 4 সকেটের সাথেও আবদ্ধ। আপনি listen 80যদি আইপিভি 6 না চান বা অন্য কোথাও বাঁধাই করতে চান না তবে এটিকে পরিবর্তন করুন ।

সাইফ বেকহানের সমাধানটি server_nameআমার ক্ষেত্রে লোকালহোস্ট হিসাবে ব্যবহার করে তবে এটি কোনও নেটওয়ার্কের মাধ্যমে পৌঁছানো যায় না।

মাইকেল নিলে থেকে সমাধানটি ভাল, তবে পিটফেলগুলি অনুসারে 301% পুনর্নির্দেশের সাথে আরও ভাল সমাধান রয়েছে))


আপনি এটিকে উদ্ধৃত করার চেষ্টা করে দুর্দান্ত, তবে 301 এইচটিটিপিএসে কাজ করে না।
কেস

5
কি কাজ করে না? উল্লিখিত সার্ভার বিভাগটি অ-এনক্রিপ্ট করা http (গুলি ছাড়াই) ট্র্যাফিকের জন্য স্থায়ীভাবে এনক্রিপ্ট করা সার্ভারে পুনঃনির্দেশ করা হবে (যে বিভাগটি 443 (https তে শুনবে তা তালিকাভুক্ত নয়)
কিমিডি

আমি এই https এবং সমস্ত কিছুর সাথে দুর্দান্ত কাজ করে দেখেছি - @ কেমিণ্ডি আমি আপনার উত্তরটি আপনার উল্লেখের সাথে আপডেট করেছি - যেহেতু আমি মনে করি এটি সঠিক উপায় এবং এটি পপিং আপ করে চলেছে! চমৎকার কাজ.
মাইকেল নিলে

কোনও ডোমেন (নন-আইপি) অনুরোধ ব্যবহার করার সময়, আমি '[::]: 80' থেকে '80' পরিবর্তন না করলে কাজ করে না।
জোসেফ লাস্ট

এটি প্রত্যাশিত আচরণ হতে পারে: trac.nginx.org/nginx/ticket/345 । শোনার বিকল্পটি বর্ণনা করতে আমি উত্তর আপডেট করেছি।
কিমিণ্ডি

20

সার্ভার ব্লকের মধ্যে আপনি নিম্নলিখিতগুলিও করতে পারেন:

# Force HTTPS connection. This rules is domain agnostic
if ($scheme != "https") {
    rewrite ^ https://$host$uri permanent;
}

2
এই কনফিগারেশনটির ফলে আমার সার্ভারটি পুনঃনির্দেশিত লুপ তৈরি করতে
পেরেছিল

সম্ভবত জায়গায় অন্য কোনও পুনর্নির্দেশের কারণ বা https আপনার সাইট / অ্যাপে সক্ষম নয়
ওরিওল

1
এই ব্যতীত অন্য কেউ কাজ করছে বলে মনে হয় না। এনগিনেক্স সংস্করণ ব্যবহার করে: এনগিনেক্স / ১.১০.০ (উবুন্টু)
ThatGuy343

https: // $ হোস্ট $ uri
এএমবি

4
আপনি কোনও ভার ভারসাম্যের পিছনে থাকলে এই উপায়!
আন্তওয়ান

17

উপরোক্ত সমস্ত সময় নতুন সাবডোমেন তৈরি হওয়ার সাথে কাজ করে না। উদাহরণস্বরূপ AAA.example.com BBB.example.com প্রায় 30 টি সাবডোমেনের জন্য।

অবশেষে নিম্নলিখিতগুলির সাথে কাজ করে একটি কনফিগার পেয়েছে:

server {
  listen 80;
  server_name _;
  rewrite ^ https://$host$request_uri? permanent;
}
server {
  listen  443;
  server_name example.com;
  ssl on;
  ssl_certificate /etc/ssl/certs/myssl.crt;
  ssl_certificate_key /etc/ssl/private/myssl.key;
  ssl_prefer_server_ciphers       on;
# ...
# rest of config here
# ...
}

ধন্যবাদ! nginx হয় 301 https://*/অন্য উত্তরগুলিতে আগে বা অনুরোধ আগেই বাতিল বা বাতিল করতে হবে। server_name _;সঙ্গে $hostউত্তর যে কৌতুক করেনি ছিল। +1
জামানট

1
এই এক অনুকূল! তবে, আমি কারও কারও কাছে _প্রকৃত ডোমেনটি প্রতিস্থাপন করার পরামর্শ দিচ্ছি , উদাহরণস্বরূপ .domain.comআমার দুটি সার্ভার ছিল এবং এনগিনেক্স দুর্ঘটনাক্রমে আমার একটি সার্ভারকে ডিফল্ট সার্ভারে পরিচালনা করছিল।
zzz

1
এটিই আমার পক্ষে একমাত্র উত্তর, যা ধন্যবাদ!
স্নোম্যান

অনেক অনেক বন্ধুকে ধন্যবাদ .. আমি অনেকগুলি সমাধানের চেষ্টা করেছি তবে কার্যকর হয়নি। এই সমাধানগুলি দুর্দান্ত and সার্ভার নাম _; এর অর্থ কী .. আমি বুঝতে পারি নি। আমাকে এই ব্যাখ্যা করুন।
পবন কুমার

6

আমি খুব দীর্ঘ সময় আগে একটি খুব গুরুত্বপূর্ণ সংশোধন নিয়ে সঠিক উত্তরের উপর একটি মন্তব্য পোস্ট করেছি, তবে আমি মনে করি যে এই সংশোধনটির নিজস্ব উত্তরে হাইলাইট করা প্রয়োজন। পূর্ববর্তী উত্তরগুলির কোনওটিই ব্যবহার করা নিরাপদ নয় যদি আপনি কোনও সময়ে সুরক্ষিত এইচটিটিপি স্থাপন এবং ব্যবহারকারীর সামগ্রীর প্রত্যাশা, ফর্ম আছে, একটি এপিআই হোস্ট করেছেন বা আপনার ওয়েবসাইটের সাথে কথা বলার জন্য কোনও ওয়েবসাইট, সরঞ্জাম, অ্যাপ্লিকেশন বা ইউটিলিটি কনফিগার করেছেন।

POSTআপনার সার্ভারে একটি অনুরোধ করা হলে সমস্যা দেখা দেয় । যদি সরল প্রতিক্রিয়াটি সরলভাবে 30xপুনর্নির্দেশ করে তবে পোস্টের সামগ্রীটি হারিয়ে যাবে। যা ঘটে তা হ'ল ব্রাউজার / ক্লায়েন্টটি অনুরোধটি এসএসএলে আপগ্রেড করে তবে POSTএকটি GETঅনুরোধে ডাউনগ্রেড করে । POSTপরামিতি হারিয়ে যাবে এবং ভুল অনুরোধ আপনার সার্ভারে তৈরি করা হবে।

সমাধান সহজ। আপনাকে HTTP 1.1 307পুনঃনির্দেশ ব্যবহার করতে হবে । এটি আরএফসি 7231 এস 6.4.7 এ বিস্তারিত রয়েছে:

  Note: This status code is similar to 302 (Found), except that it
  does not allow changing the request method from POST to GET.  This
  specification defines no equivalent counterpart for 301 (Moved
  Permanently) ([RFC7238], however, defines the status code 308
  (Permanent Redirect) for this purpose).

সমাধান, গৃহীত সমাধান থেকে অভিযোজিত, 307আপনার পুনর্নির্দেশ কোড ব্যবহার করা হয়:

server {
       listen         80;
       server_name    my.domain.com;
       return         307 https://$server_name$request_uri;
}

server {
       listen         443 ssl;
       server_name    my.domain.com;
       # add Strict-Transport-Security to prevent man in the middle attacks
       add_header Strict-Transport-Security "max-age=31536000"; 

       [....]
}

4

আমি এটি এইভাবে পরিচালনা করতে পেরেছি:

server {
listen 80;
listen 443 ssl;

server_name domain.tld www.domain.tld;

# global HTTP handler
if ($scheme = http) {
        return 301 https://www.domain.tld$request_uri;
}

# global non-WWW HTTPS handler
if ($http_host = domain.tld){
        return 303 https://www.domain.tld$request_uri;
}
}

https://stackoverflow.com/a/36777526/6076984


আপডেট সংস্করণ, ডাব্লু
স্ট্যামস্টার

4

আমি একটি এডাব্লুএস ইএলবির পিছনে এনগনিক্স চালাচ্ছি। ELB HTTP- র মাধ্যমে এনগনিক্সের সাথে কথা বলছে। ELB- র ক্লায়েন্টদের কাছে পুনঃনির্দেশ পাঠানোর কোনও উপায় নেই, তাই আমি এক্স-ফরওয়ার্ড-প্রোটো শিরোনামটি পরীক্ষা করে পুনর্নির্দেশ করি:

if ($http_x_forwarded_proto != 'https') {
    return 301 "https://www.exampl.com";
}

1

আপনি যদি return 301 https://$host$request_uri;৮০ বন্দরটিতে ডিফল্ট প্রতিক্রিয়া হিসাবে থাকেন তবে আপনার সার্ভারটি অচিরেই বা পরে ওপেন প্রক্সির একটি তালিকা পেতে পারে [1] এবং ইন্টারনেটে ট্র্যাফিক অন্যত্র প্রেরণের জন্য আপত্তিজনক নির্যাতন শুরু করতে পারে। যদি আপনার লগগুলি এই জাতীয় বার্তাগুলি পূরণ করে তবে আপনি জানেন যে এটি আপনার সাথে ঘটেছিল:

42.232.104.114 - - [25/Mar/2018:04:50:49 +0000] "GET http://www.ioffer.com/i/new-fashion-fine-gold-bracelet-versaec-bracelet-641175733 HTTP/1.1" 301 185 "http://www.ioffer.com/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Hotbar 4.1.8.0; RogueCleaner; Alexa Toolbar)"

সমস্যাটি হ'ল $hostব্রাউজারটি এইচডিটিপির Hostপ্রারম্ভিক লাইন থেকে শিরোনাম বা এমনকি হোস্টনামে যা কিছু প্রেরণ করে তা আবার প্রতিধ্বনিত করবে :

GET http://www.ioffer.com/i/new-fashion-fine-gold-bracelet-versaec-bracelet-641175733 HTTP/1.1

সেই সমস্যাটির কারণে, এখানে আরও কয়েকটি উত্তর $server_nameপরিবর্তে ব্যবহারের পরামর্শ দেয় $hostআপনি ঘোষণাপত্রে $server_nameযা রেখেছিলেন তা সর্বদা মূল্যায়ন করে । তবে যদি আপনার সেখানে একাধিক সাবডোমেন থাকে বা একটি ওয়াইল্ডকার্ড ব্যবহার করেন তবে এটি কার্যকর হবে না, কারণ ঘোষণার পরে কেবল প্রথম প্রবেশটি ব্যবহার করে এবং আরও গুরুত্বপূর্ণভাবে কেবল একটি ওয়াইল্ডকার্ডের প্রতিধ্বনি হবে (এটি প্রসারিত করবেন না)।server_name$server_nameserver_name

তাহলে সুরক্ষা বজায় রেখে কীভাবে একাধিক ডোমেন সমর্থন করবেন? আমার নিজের সিস্টেমে আমি প্রথমেdefault_server ব্যবহার না করে এমন একটি ব্লক তালিকাভুক্ত করে $hostএবং তারপরে একটি ওয়াইল্ডকার্ড ব্লককে তালিকাবদ্ধ করে এই দ্বিধাটির মোকাবিলা করেছি :

server {
  listen 80 default_server;
  server_name example.com;
  return 301 https://example.com$request_uri;
}
server {
  listen 80;
  server_name *.example.com;
  return 301 https://$host$request_uri;
}

(আপনি দ্বিতীয় ব্লকে একাধিক ডোমেন তালিকাভুক্ত করতে পারেন))

এই সংমিশ্রণের সাথে example.comমেলে না এমন ডোমেনগুলি হার্ডকডযুক্ত (সর্বদা ) কোথাও পুনঃনির্দেশিত হবে এবং আপনার নিজের সাথে মেলে এমন ডোমেনগুলি সঠিক জায়গায় যাবে। আপনার সার্ভারটি ওপেন প্রক্সি হিসাবে কার্যকর হবে না, তাই আপনি সমস্যা আকর্ষণ করবেন না।

আপনি যা-তা বোধ হয় তবে আমি আপনার কাছে বানাতে পারে অনুমান করা default_serverব্লক ম্যাচ কেউ আপনার বৈধ ডোমেইন এবং কিছু আপত্তিকর পরিবেশন করা। । । ।

[1] প্রযুক্তিগতভাবে "প্রক্সি "টি ভুল শব্দ, কারণ আপনার সার্ভারটি ক্লায়েন্টদের জন্য অনুরোধগুলি পূরণ করছে না এবং কেবল পুনঃনির্দেশ পাঠিয়েছে, তবে সঠিক শব্দটি কী হবে তা আমি নিশ্চিত নই। আমি লক্ষ্যটি কী তাও নিশ্চিত নই, তবে এটি আপনার লগগুলিকে শব্দের সাথে পূর্ণ করে এবং আপনার সিপিইউ এবং ব্যান্ডউইদথকে গ্রাস করে, তাই আপনি এটিও থামিয়ে দিতে পারেন।


0

দেখে মনে হচ্ছে সত্যই কেউ এটি 100% সঠিকভাবে পায় নি। একটি পূর্ণ ওয়েবসারভারের জন্য পোর্ট 80 এর অনুরোধগুলি তাদের 443 সমতুল্যর কাছে যেতে, আপনি ক্যাচ-সমস্ত নাম নির্দিষ্ট করার জন্য সার্ভার_নামের নির্দেশিকা নয়, শোনার নির্দেশিকা ব্যবহার করতে হবেHttps://nginx.org/en/docs/http/request_processing.html আরও দেখুন

সার্ভার
    80 ডিফল্ট শুনুন;
    শুনুন [::]: 80 ডিফল্ট;
      307 https: // $ হোস্ট $ রিকোয়েস্ট_উইরি রিটার্ন করুন;
}
  • $ হোস্ট সাবডোমেনের নামগুলি ক্যাচ করে।
  • 307 এবং 308 এ উভয়ই POST এবং GET অনুরোধের ইউআরআই অন্তর্ভুক্ত করে।
  • 307 অস্থায়ী, সম্পূর্ণ পরীক্ষার পরে স্থায়ী 308 এ পরিবর্তন করুন:

এবং নিশ্চিত হয়ে নিন যে আপনি ইতিমধ্যে /etc/nginx/conf.d/ এ কী আছে তা যাচাই করেছেন কারণ আমার প্রায়শই এমন সমস্যা ছিল না যেখানে ডিফল্ট.কনফ কিছু বিদ্যমান vhost ফিরিয়ে দেয়। আমার এনজিনেক্স ইস্যুগুলির সাথে কাজ করার ক্রমটি সর্বদা ডিফল্ট ফাইলটি সরিয়ে নিয়ে শুরু হয়, এটি কোথায় ভুল হয় তা দেখার জন্য লাইন দিয়ে লাইনে মন্তব্য করে পিছনে ফেলে।


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.