Client VPN ক্লায়েন্টকে একটি ঠিকানা দেয়, হ্যান্ডশেক শেষ হয়, তবু সংযোগটি কোথাও পৌঁছায় না। সার্টিফিকেট বা ক্লায়েন্ট সংস্করণে হাত দেওয়ার আগে এন্ডপয়েন্টের নিজের রুট টেবিলটি দেখুন। AWS Client VPN এন্ডপয়েন্ট তখনই একটি প্যাকেট ফরওয়ার্ড করে যখন তার একটি রুট গন্তব্যের প্রিফিক্স ঢেকে রাখে; কিছু না মিললে প্যাকেটটি এন্ডপয়েন্টেই বাতিল হয় এবং লক্ষ্য হোস্ট কখনো SYN দেখে না।

এটি ফরওয়ার্ডিংয়ের সিদ্ধান্ত, প্রমাণীকরণের নয়। এটি ঘটে টানেল ওঠার পরে এবং অনুমোদন নিয়ম মূল্যায়নের পরে, তাই বৈধ সার্টিফিকেট আর বৈধ গ্রুপও মৃত সংযোগ তৈরি করতে পারে।

এন্ডপয়েন্ট কেবল তাই ফরওয়ার্ড করে যা তার রুট টেবিল ঢেকে রাখে

প্রতিটি রুট হলো একটি গন্তব্য CIDR এবং যে সাবনেট ট্রাফিক পাবে। এন্ডপয়েন্ট ক্লায়েন্টের গন্তব্যকে ওই তালিকার সঙ্গে মেলায়, মিলে যাওয়া এন্ট্রি বেছে নেয় এবং প্যাকেটটি সংশ্লিষ্ট সাবনেটে পাঠায়। এন্ট্রি না থাকলে পরের হপও নেই.

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

চিরাচরিত অমিল হলো পিয়ারড VPC। কেউ 10.20.0.0/24-এর জন্য রুট যোগ করে, অথচ হোস্টটি থাকে 10.20.4.0/24-এ, তাই ঠিকানাটি প্রতিটি এন্ট্রির বাইরে পড়ে। ক্লায়েন্ট পাশের ক্যাপচার বারবার SYN দেখায় কিন্তু কোনো উত্তর নেই, আর লক্ষ্যের লগ কিছুই দেখায় না।

সার্টিফিকেটের আগে রুট তালিকা পড়ুন

এন্ডপয়েন্টের রুটগুলো আলাদা অবজেক্ট, তাই VPC টেবিল পড়ার বদলে সরাসরি সেগুলো জিজ্ঞাসা করুন:

aws ec2 describe-client-vpn-routes --client-vpn-endpoint-id cvpn-endpoint-0123456789abcdef0 --query 'Routes[].{Dest:DestinationCidr,Target:TargetSubnet,Origin:Origin}'

ব্যর্থ ক্লায়েন্ট থেকে সঠিক ঠিকানা ও প্রিফিক্স দৈর্ঘ্য নিন, তারপর অক্ষর ধরে ধরে কভারেজ যাচাই করুন। দীর্ঘতম প্রিফিক্স ম্যাচ প্রযোজ্য, তাই সরু রুট অন্য জায়গায় নির্দেশ করলে চওড়া রুট আপনাকে বাঁচায় না।

for_each দিয়ে প্রতি গন্তব্যে একটি রিসোর্স

হাতে লেখা রুট ব্লক কনসোলে কেউ প্রিফিক্স যোগ করার মুহূর্তেই সরে যায়। গন্তব্যগুলো একটি ম্যাপে রাখুন এবং প্রতি কী-তে একটি রিসোর্স তৈরি করুন, যাতে প্রতিটি যোগ বা অপসারণ আলাদা থাকে।

variable "client_vpn_routes" {
  type = map(string)
  default = {
    "10.20.0.0/16"  = "subnet-0aa11bb22cc33dd44"
    "172.31.0.0/20" = "subnet-0aa11bb22cc33dd44"
  }
}

resource "aws_ec2_client_vpn_route" "this" {
  for_each               = var.client_vpn_routes
  client_vpn_endpoint_id = var.client_vpn_endpoint_id
  destination_cidr_block = each.key
  target_vpc_subnet_id   = each.value
  depends_on             = [aws_ec2_client_vpn_network_association.this]
}

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

আপনি তৈরি করেননি এমন এন্ডপয়েন্ট গ্রহণ করা

বেশিরভাগ দল কনসোলে তৈরি একটি এন্ডপয়েন্ট উত্তরাধিকারে পায়, তাই কোনো রুট কোড থাকে না। শুধু Terraform-এ রুট আনতে দ্বিতীয় এন্ডপয়েন্ট দাঁড় করাবেন না।

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

প্যাকেট যেভাবে চলে সেই ক্রমে অনুসরণ করুন

রুট থাকা সত্ত্বেও সংযোগ ব্যর্থ হলে উপরের স্তরে অনুমান না করে পথটি ক্রমে হাঁটুন।

  1. রুট: একটি প্রিফিক্স গন্তব্য ঢাকে এবং এন্ডপয়েন্টের সঙ্গে সংশ্লিষ্ট সাবনেটে নির্দেশ করে।
  2. অনুমোদন: একটি অনুমোদন নিয়ম ব্যবহারকারীর গ্রুপের জন্য ওই গন্তব্য অনুমোদন করে। কেবল রুট কখনো প্রবেশাধিকার দেয় না।
  3. ফিরতি পথ: লক্ষ্য সাবনেটের রুট টেবিল উত্তরগুলো এন্ডপয়েন্টের দিকে ফেরত পাঠায়, আর সিকিউরিটি গ্রুপ ক্লায়েন্ট ঠিকানা পুল থেকে পোর্টটি অনুমোদন করে।
  4. অ্যাপ্লিকেশন: ক্লায়েন্ট থেকে সত্যিকারের TCP সংযোগ খুলুন, তারপর নিশ্চিত করুন লক্ষ্যের লগে পুল থেকে প্রত্যাশিত সোর্স ঠিকানা দেখাচ্ছে।

প্রতি apply-তে একটি প্রিফিক্স বদলান, পরে রুট তালিকা আবার পড়ুন, এবং গন্তব্য, অনুমোদনকারী নিয়ম ও ফিরতি পথ একসঙ্গে লিখে রাখুন। পরবর্তী যে ব্যক্তি প্রত্যাখ্যাত সংযোগ ডিবাগ করবেন, তাঁর সার্টিফিকেট-তত্ত্ব নয়, এই তালিকা থেকেই শুরু করা উচিত।

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