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

একটি সংযোগ আসলে কী যাচাই করে

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

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

এমন হোস্টে রুট তৈরি করুন যেটি কখনো ঠিকানা পায় না

অফলাইন রুট খুব কম ব্যবহৃত হয়: ইন্টারমিডিয়েট CA সার্টিফিকেট সাইন করতে, এবং পরে সেটি নবায়ন বা প্রত্যাহার করতে। বাকি সবকিছু এক স্তর নিচে ঘটে। নেটওয়ার্কের বাইরে রাখা একটি মেশিনে রুটের কাজ করুন, সম্ভব হলে একটি লাইভ সিস্টেম থেকে, এবং কে ঘরে ছিল তা লিখে রাখুন। কমান্ডগুলো OpenSSL 1.1.1 বা নতুনতর ধরে নেয়, কারণ পুরনো বিল্ডে -addext নেই।

openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out root.key
openssl req -x509 -new -key root.key -sha256 -days 7300 \
  -subj "/CN=Example VPN Root CA" -out root.crt \
  -addext "basicConstraints=critical,CA:TRUE" \
  -addext "keyUsage=critical,keyCertSign,cRLSign"

সাইনিং হোস্টে ইন্টারমিডিয়েট তৈরি করুন এবং কেবল তার অনুরোধ অফলাইন মেশিনে নিয়ে যান। রুট সেই অনুরোধটি শূন্য পাথ দৈর্ঘ্য দিয়ে সাইন করে, তাই ইন্টারমিডিয়েট এন্ডপয়েন্ট সার্টিফিকেট সাইন করতে পারে কিন্তু তার নিচে আরেকটি CA তৈরি করতে পারে না। ওই একটি এক্সটেনশন একটি আপসকৃত সাইনিং হোস্টকে রুট-সমতুল্য কর্তৃত্ব তৈরি করা থেকে থামায়। ECDSA ব্যবহার করুন কেবল যদি প্রতিটি ক্লায়েন্ট OpenVPN 2.4 বা নতুনতর চালায়; অন্যথায় RSA কী তৈরি করুন এবং প্রবাহ একই রাখুন।

openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out intermediate.key
openssl req -new -key intermediate.key -subj "/CN=Example VPN Intermediate CA" -out intermediate.csr
openssl x509 -req -in intermediate.csr -CA root.crt -CAkey root.key \
  -CAcreateserial -days 3650 -sha256 -extfile intermediate.ext -out intermediate.crt

intermediate.ext-এ basicConstraints=critical,CA:TRUE,pathlen:0, keyUsage=critical,keyCertSign,cRLSign এবং authorityKeyIdentifier=keyid:always থাকে। সাইনিং হোস্ট পুনরায় সংযুক্ত হওয়ার আগে রুট কী তার সিন্দুকে ফিরিয়ে দিন। যদি রুটকে ইন্টারমিডিয়েট প্রত্যাহার করার ক্ষমতা দিতে হয়, তবে openssl x509 -req-এর বদলে রুট-স্তরের index.txt-এর বিপরীতে openssl ca -config root.cnf -extensions intermediate_ca দিয়ে এটি সাইন করুন, যাতে সিরিয়াল রেকর্ড হয়; তারপর ফলাফল রুট তালিকাটি ক্লায়েন্ট প্রোফাইলের ভিতরে পাঠান, যেখানে একটি ফাইলভিত্তিক crl-verify তা শুরুতে পড়ে। ক্লায়েন্টদের উভয় CA সার্টিফিকেটসহ একটি বান্ডল পাঠান; কেবল একটি লিফ রুটের বিপরীতে যাচাই হবে না।

ডেটাবেসসহ ইন্টারমিডিয়েট থেকে লিফ ইস্যু করুন

openssl x509 -req দিয়ে সাইন করা কাজ করে যতক্ষণ প্রত্যাহারের দরকার না হয়, কারণ কিছুই সিরিয়াল রেকর্ড করে না। প্রথম সার্টিফিকেট থেকেই openssl ca ব্যবহার করুন যাতে সিরিয়াল, মেয়াদ এবং প্রত্যাহারের অবস্থা এক ডেটাবেসে থাকে। ডেটাবেস ফাইলগুলো একবার তৈরি করুন, তারপর কনফিগ সেগুলোর দিকে নির্দেশ করুন:

mkdir -p /etc/vpn-ca/intermediate/newcerts
touch /etc/vpn-ca/intermediate/index.txt
echo 1000 > /etc/vpn-ca/intermediate/serial
echo 1000 > /etc/vpn-ca/intermediate/crlnumber
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = /etc/vpn-ca/intermediate
database = $dir/index.txt
new_certs_dir = $dir/newcerts
serial = $dir/serial
crlnumber = $dir/crlnumber
certificate = $dir/intermediate.crt
private_key = $dir/intermediate.key
default_md = sha256
default_days = 365
default_crl_days = 30
unique_subject = no
policy = policy_any
[ policy_any ]
commonName = supplied
[ server_cert ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature
extendedKeyUsage = serverAuth
subjectAltName = @server_names
[ client_cert ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature
extendedKeyUsage = clientAuth
[ server_names ]
DNS.1 = vpn.example.com

কী ব্যবহারের লাইনটি একটি ECDSA কী ধরে নেয়; RSA-এর জন্য keyEncipherment যোগ করুন। প্রতিটি ক্লায়েন্টকে তার নিজস্ব কমন নেম দিন, কারণ OpenVPN সেই ক্ষেত্র দিয়ে একটি সংযোগ চিহ্নিত করে, এবং একই CN=vpn-client ভাগ করা দুটি ল্যাপটপ লগে, client-config-dir নিয়মে বা কোনো ব্যবহারকারীভিত্তিক পুশে আলাদা করা যায় না, আর আপনি সেই অ্যাট্রিবিউশন হারান যা প্রত্যাহারের সিদ্ধান্তকে রক্ষণযোগ্য করে। একটি লিফ এভাবে ইস্যু ও যাচাই করুন:

openssl req -new -key alice.key -subj "/CN=alice-laptop" -out alice.csr
openssl ca -config intermediate.cnf -extensions client_cert -in alice.csr -out alice.crt -batch
openssl verify -CAfile ca-bundle.crt -untrusted intermediate.crt alice.crt

সাইনিং কী VPN হোস্টে অনুলিপি না করে একটি নীতি সীমার পিছনে রাখুন: একটি ছোট পরিষেবা যা অনুরোধ প্রমাণীকরণ করে, কমন নেমটি অনুমোদিত তালিকার বিপরীতে যাচাই করে এবং কেবল সার্টিফিকেট ফেরত দেয়। প্রতিটি সিরিয়াল লগ করুন; লগই একটি সার্টিফিকেট এবং যিনি এটি চেয়েছিলেন তার মধ্যে একমাত্র সংযোগ।

রুট জাগিয়ে না তুলে প্রত্যাহার প্রকাশ করুন

ক্লায়েন্ট সার্টিফিকেট ইন্টারমিডিয়েট প্রত্যাহার করে, কখনো রুট নয়। রুট তালিকা কেবল তখনই গুরুত্বপূর্ণ যখন একটি ইন্টারমিডিয়েট পুড়ে যায়। সার্ভারকে crl-verify দিয়ে ইন্টারমিডিয়েট তালিকার দিকে নির্দেশ করুন। একটি ফাইলভিত্তিক CRL পরিষেবা শুরুর সময় লোড হয়, তাই প্রতিবার পুনরুত্পাদনের পর পুনরায় লোড করুন; ডিরেক্টরি রূপটি সংযোগের সময় অবস্থা পড়ে এবং প্রতি সিরিয়ালে একটি ফাইল খরচ করে।

একই ডেটাবেস থেকে দুটি কমান্ড দিয়ে প্রত্যাহার করুন ও পুনরায় তৈরি করুন:

openssl ca -config intermediate.cnf -revoke /etc/vpn-ca/intermediate/newcerts/1001.pem
openssl ca -config intermediate.cnf -gencrl -out /etc/openvpn/crl.pem

তারপর ঘড়ির দিকে নজর রাখুন। একটি CRL একটি পরবর্তী-হালনাগাদ ক্ষেত্র বহন করে, এবং সেই তারিখ পার হয়ে গেলে যাচাইকারী পক্ষ তালিকাটি উপেক্ষা না করে প্রত্যাখ্যান করে। default_crl_days = 30 দিয়ে মাসিক পুনরায় তৈরি করলে কিছুটা সুযোগ থাকে; বছরে একবার করলে থাকে না। ছোট লিফ আয়ু বেশি নির্ভরযোগ্য নিয়ন্ত্রণ, কারণ প্রত্যাহার কেবল সেখানেই প্রযোজ্য যেখানে তালিকা দেখা হয়।

চেইন পরীক্ষা করুন, তারপর আনুষ্ঠানিকতা লিখে রাখুন

নকশায় বিশ্বাস করার আগে চারটি ব্যর্থতা পুনরুৎপাদন করুন। openssl verify -CAfile ca-bundle.crt -untrusted intermediate.crt server.crt দিয়ে চেইন যাচাই করুন। একটি মেয়াদোত্তীর্ণ ক্লায়েন্ট সার্টিফিকেট দিয়ে সংযোগ করুন এবং সার্ভার তা প্রত্যাখ্যান করে কি না নিশ্চিত করুন। একটি পরীক্ষামূলক ক্লায়েন্ট প্রত্যাহার করুন, পুনরায় লোড করুন এবং তালিকা কার্যকর হয় কি না নিশ্চিত করুন। একটি হোস্টের ঘড়ি এক দিন এগিয়ে দিন, কারণ ভুল ঘড়ি এমন সার্টিফিকেট ইস্যু ও প্রত্যাখ্যান করতে পারে যা অন্যত্র বৈধ দেখায়।

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

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

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