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

কিছু তুলনা করার আগে পথটি বর্ণনা করুন:

Client -> approved reverse proxy -> application origin

সেই বিন্যাসে মূল সার্ভারের সকেট পিয়ার সাধারণত প্রক্সি হয়, এবং একটি ফরওয়ার্ডিং হেডার প্রক্সির ক্লায়েন্ট সম্পর্কিত দাবি বহন করতে পারে। এর মূল্য আসে সেই প্রক্সির সঙ্গে নিয়ন্ত্রিত সম্পর্ক থেকে, হেডারের নাম থেকে নয়।

দুই ধরনের ঠিকানা-প্রমাণ

সকেট পিয়ার একটি TCP সংযোগ সম্পর্কিত সত্য: ওই ঠিকানা থেকে কিছু একটা হ্যান্ডশেক সম্পন্ন করেছে। এটি অবশ্যই সেই মানুষ, ডিভাইস বা অ্যাকাউন্ট নয় যেটি আপনার কাছে গুরুত্বপূর্ণ, কারণ একটি VPN বা Tor এক্সিট বৈধভাবে সেই উৎস হতে পারে যা কোনো সেবা পর্যবেক্ষণ করে। এটি তবুও একমাত্র ঠিকানা যা হোস্ট নিজেই যাচাই করেছে, এবং এর সমস্ত মূল্য এখানেই।

একটি ফরওয়ার্ডিং ফিল্ড একটি শৃঙ্খল সম্পর্কে মেটাডেটা। X-Forwarded-For, X-Real-IP এবং প্রমিত Forwarded ফিল্ডটি এমন যেকোনো ক্লায়েন্ট লিখতে পারে যে এমন প্রান্তে পৌঁছায় যা সেগুলো প্রতিধ্বনি করে, তাই তাদের বিশ্বাসযোগ্যতা সম্পূর্ণভাবে নির্ভর করে কাকে সেগুলো নির্ধারণ করার অনুমতি দেওয়া হয়েছিল তার উপর।

দুটিকেই অনুরোধ প্রসঙ্গে আলাদা নামে রাখুন। যে অ্যাপ্লিকেশন পিয়ারকে হেডার দিয়ে ওভাররাইট করে, সেটি পরে আস্থার ত্রুটি পুনর্গঠনের ক্ষমতা হারায়, আর ঠিক তখনই আপনার সেটি প্রয়োজন হয়।

হেডার কখনো সংযোগের পথ বদলায় না

ফরওয়ার্ডিং ফিল্ডে ঠিকানা লেখা সার্ভারে আসা TCP সংযোগের উৎস বদলায় না, এবং পথের কোথাও রাউটিং বদলায় না। সাধারণ VPN রাউটিং বা উৎস NAT কোনো HTTP হেডার ছাড়াই ট্রাফিক পৌঁছে দেয়। একইভাবে, একটি ট্রানজিট গেটওয়ে TLS প্রান্তের বিন্যাস না বদলে সঠিকভাবে সুরক্ষিত HTTPS বিনিময় পুনর্লিখন করে না।

উল্টো ভুলটিও সমান সাধারণ: HTTPS ক্লায়েন্টের দেওয়া ফরওয়ার্ডিং হেডারকে সত্য করে না। এটি মিথ্যা দাবির পরিবহনকে সত্য দাবির মতোই ভালোভাবে সুরক্ষা দেয়।

যদি কোনো সহকর্মী রাউটিং সমস্যা ঠিক করতে হেডার পরিবর্তনের প্রস্তাব দেন, তাহলে রোগনির্ণয় ইতিমধ্যে ভুল হয়ে গেছে। পথটি ঠিক করুন, অথবা যে প্রক্সি কনফিগারেশন হেডারটি লেখে সেটি ঠিক করুন।

যে প্রক্সি দাবি করতে পারে তার নাম দিন

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

NGINX রিয়েল-IP মডিউল এই বিভাজন পরিষ্কারভাবে দেখায়। set_real_ip_from যে প্রেরকদের দাবি গণ্য হয় তাদের নাম দেয়, এবং real_ip_header কোন ফিল্ড এটি বহন করে তা বলে; প্রথমটি আস্থা করে, দ্বিতীয়টি কেবল বলে কোথায় দেখতে হবে।

set_real_ip_from 10.20.0.0/24;
real_ip_header X-Forwarded-For;
# real_ip_recursive off - take the rightmost value in the field
# real_ip_recursive on  - walk the list back past every trusted address

কেবল একটি হেডার-নির্বাচন নির্দেশ নিজে থেকে মানটির প্রেরক কে সে সম্পর্কে কিছুই প্রতিষ্ঠা করে না।

পরিবহন নিরাপত্তা আপনার আস্থাভাজন উপাদানগুলোর মধ্যে পুরো পথ জুড়ে চলতে হবে। সঠিকভাবে স্বাভাবিক করা একটি প্রান্ত সেই মূল্য হারায় ঠিক যখন নিচের দিকে একটি অরক্ষিত ধাপ কাউকে যাত্রাকালে দাবিটি সম্পাদনা করার সুযোগ দেয়।

বহু-ধাপ শৃঙ্খল সচেতনভাবে সামলান

একাধিক প্রক্সির স্পষ্ট শৃঙ্খল মডেল প্রয়োজন। কোনো ব্লগ পোস্ট তাই করেছে বলে কমা-বিভক্ত বাঁদিকের বা ডানদিকের মান নেবেন না; খুঁজে বের করুন আপনার কোন প্রক্সি যোগ করে, কোনটি প্রতিস্থাপন করে আর কোনটি আগত ফিল্ড সংরক্ষণ করে। উদাহরণস্বরূপ, NGINX তার বিশ্বস্ত সেটের বিপরীতে তালিকাটি পেছনের দিকে হাঁটতে পারে এবং প্রথম যে ঠিকানাটি তার নয় সেখানে থামতে পারে, আর এটি সেই পণ্যের নিয়ম, প্রতিটি ফ্রেমওয়ার্ক যে আইন মানে তা নয়। নিজের প্রক্সির নথি একই দুই প্রশ্ন নিয়ে পড়ুন: এটি কোন মান বেছে নেয়, এবং কোন প্রেরককে বিশ্বাস করে?

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

যখন একটি ধাপ যোগ করেন, ওই নথিটি পুনর্বিবেচনা করুন। বিশ্বস্ত প্রক্সির সামনে সন্নিবেশিত একটি নতুন লোড ব্যালান্সার কেউ অ্যাপ্লিকেশন সম্পাদনা না করেই কোন ঠিকানা জিতবে তা বদলে দিতে পারে।

উভয় পর্যবেক্ষণ লগে রাখুন

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

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

সম্পর্কিত নিবন্ধ