Ubuntu میں اپنا CA trust store میں کیسے شامل کریں
Ubuntu میں OpenSSL سے private CA اور leaf certificate بنائیں، پھر root کو /usr/local/share/ca-certificates میں رکھ کر update-ca-certificates چلائیں تاکہ internal HTTPS پر اعتماد ہو۔
اپنا CA، Ubuntu کے trust store میں شامل کریں
اپنا CA، Ubuntu کے trust store میں شامل کرنے کے لیے root certificate کو /usr/local/share/ca-certificates/ میں ایسی فائل کے نام سے copy کریں جو .crt پر ختم ہوتا ہو، پھر sudo update-ca-certificates چلائیں۔ CA (certificate authority) ایک key pair ہوتا ہے جس کے certificate کو دوسرے certificates پر دستخط کرنے کی اجازت ہوتی ہے۔ جب machine آپ کے root پر اعتماد کرنے لگتی ہے تو اس root کے دستخط شدہ ہر certificate کو قبول کیا جاتا ہے، اس لیے آپ کی اپنی services کے درمیان HTTPS verification میں ناکام نہیں ہوتا۔
یہ guide پورا chain، openssl کے ذریعے offline تیار کرتی ہے۔ آپ root key اور root certificate بناتے ہیں، server کے لیے ایک leaf certificate جاری کرتے ہیں، پھر root install کرتے ہیں اور دیکھتے ہیں کہ verification کی وہی command اپنا جواب کیسے بدلتی ہے۔ یہی ترتیب اس عمل کا مقصد ہے: install سے پہلے اور بعد میں verification کرنے سے معلوم ہوتا ہے کہ نتیجہ install کی وجہ سے بدلا ہے۔
Ubuntu 24.04 میں default image پر OpenSSL 3 اور ca-certificates package شامل ہوتے ہیں، اس لیے پہلے کچھ install کرنے کی ضرورت نہیں ہے (August 2026 میں جانچا گیا)۔
اپنا CA کب چلانا چاہیے؟
Let's Encrypt جیسے public CA کو public DNS میں ایک نام اور ایسا server درکار ہوتا ہے جس تک یہ پہنچ سکے۔ Internal names اس مقصد کے لیے قابل قبول نہیں ہوتے۔ Private network پر موجود database یا tunnel سے منسلک admin panel public certificate حاصل نہیں کر سکتا، اور صرف certificate حاصل کرنے کے لیے اسے internet پر exposed بھی نہیں کرنا چاہیے۔
Ubuntu پر self-signed certificate صرف ایک host کا مسئلہ حل کرتا ہے۔ ہر client کو اس ایک certificate پر trust کرنا پڑتا ہے، اور اگلے host کے لیے یہی کام دوبارہ کرنا پڑتا ہے۔ Private CA اس فیصلے کو ایک سطح اوپر منتقل کرتا ہے۔ Clients ایک بار root پر trust کرتے ہیں، پھر root کے جاری کردہ ہر certificate پر trust کرتے ہیں، بشمول ان hosts کے certificates کے جو ابھی موجود نہیں ہیں۔
اس کی لاگت حقیقی ہے۔ Root key ان تمام certificates پر دستخط کر سکتی ہے جن کی constraints اجازت دیں، اس لیے جو شخص ca.key پڑھ لے وہ ایسے certificates جاری کر سکتا ہے جنہیں آپ کی machines قبول کریں گی۔ اسے اسی طرح محفوظ رکھیں جیسے SSH key management میں private key کو محفوظ رکھتے ہیں۔ اگر کسی service کا public DNS name ہے تو یہ سب چھوڑ دیں اور public CA استعمال کریں: nginx اور Let's Encrypt کے ساتھ Certbot کم محنت طلب ہے اور client side پر کچھ install کرنے کی ضرورت نہیں ہوتی۔
CA key اور root certificate بنائیں
ایسی directory میں کام کریں جسے صرف آپ کا user کھول سکتا ہو۔ root key اس directory سے کبھی باہر نہ جائے۔
install -d -m 700 ~/ca
cd ~/ca
openssl genrsa -aes256 -out ca.key 4096
chmod 600 ca.key-aes256 آپ کے منتخب کردہ passphrase سے key کو encrypt کرتا ہے، اور بعد میں اس key سے sign کرنے والی ہر command یہ passphrase مانگتی ہے۔ -aes256 کو ہٹا دیں تو key disk پر plain text میں محفوظ رہتی ہے۔ ایسی صورت میں backup یا دوسرے admin account تک رسائی رکھنے والا شخص وہ certificates جاری کر سکتا ہے جن پر آپ کی machines اعتماد کرتی ہیں۔
اب root certificate بنائیں، جسے CA key خود اپنے لیے sign کرتی ہے۔
openssl req -x509 -new -key ca.key -sha256 -days 3650 \
-subj "/O=Example Internal/CN=Example Internal Root CA" \
-addext "basicConstraints=critical,CA:TRUE,pathlen:0" \
-addext "keyUsage=critical,keyCertSign,cRLSign" \
-addext "subjectKeyIdentifier=hash" \
-addext "nameConstraints=critical,permitted;DNS:internal.example" \
-out ca.crtinternal.example کو اس name suffix سے تبدیل کریں جسے آپ حقیقت میں استعمال کرتے ہیں۔ آخری extension برقرار رکھنے سے پہلے اگلا section پڑھیں۔
ہر extension ایک کام کرتا ہے۔
basicConstraintsمیںCA:TRUEاس certificate کو CA certificate بناتا ہے۔ اس کے بغیر client اس key سے sign کیے گئے کسی بھی certificate کو reject کر دیتا ہے، چاہے signature درست ہو۔pathlen:0بتاتا ہے کہ CA leaf certificates sign کر سکتا ہے، لیکن اس کے نیچے مزید CAs کو sign نہیں کر سکتا۔keyUsagekey کو certificates اور revocation lists sign کرنے تک محدود کرتا ہے۔ اس طرح یہی key غلطی سے TLS server key کے طور پر استعمال نہیں ہو سکتی۔subjectKeyIdentifierroot کو ایک identifier دیتا ہے جس کی طرف leaf certificates واپس اشارہ کرتے ہیں۔ اسی سے client کو ایسے store میں درست issuer ملتا ہے جس میں چند سو certificates موجود ہوں۔nameConstraintsان names کو محدود کرتا ہے جن کی توثیق کرنے کا اختیار اس CA کو حاصل ہے۔
یہ فرض کرنے کے بجائے کہ command نے آپ کی مراد کے مطابق کام کیا، بنائی گئی چیز کی تفصیل دوبارہ دیکھیں۔
openssl x509 -noout -subject -issuer -serial -dates -in ca.crt
openssl x509 -noout -text -in ca.crtSubject اور issuer میں ایک ہی string ظاہر ہوتی ہے، کیونکہ root certificate خود کو sign کرتا ہے۔ serial اور دونوں dates ابھی بنائی گئی file سے آتی ہیں، اس لیے انہیں کسی guide سے لینے کے بجائے اسی output سے حاصل کریں۔
اپنے CA کے دستخط کرنے کے اختیار کو محدود کریں
System store میں موجود root پر انٹرنیٹ کے ہر نام کے لیے اعتماد کیا جاتا ہے، جب تک آپ اس کے برعکس واضح طور پر نہ کہیں۔ ایک سرور کی ایک فائل میں اتنا اختیار رکھنا بڑا خطرہ ہے۔ nameConstraints اس اختیار کو محدود کرتا ہے۔ Root میں permitted;DNS:internal.example شامل ہونے کے بعد، اس CA سے internal.example کے باہر کسی نام کے لیے بنائی گئی chain مسترد ہو جاتی ہے، چاہے signature درست ہو۔
اعتماد کرنے کے بجائے اس کی جانچ کریں۔
openssl req -new -newkey rsa:2048 -nodes -keyout /tmp/outside.key -out /tmp/outside.csr \
-subj "/CN=www.example.com"
openssl x509 -req -in /tmp/outside.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-days 30 -sha256 \
-extfile <(printf 'subjectAltName=DNS:www.example.com\n') -out /tmp/outside.crt
openssl verify -CAfile ca.crt /tmp/outside.crt
echo $?Certificate جاری ہو جاتا ہے، کیونکہ آپ کا CA ہر اس چیز پر دستخط کرتا ہے جس پر آپ اس سے دستخط کرنے کو کہیں۔ ناکامی verification کے مرحلے پر ہوتی ہے: exit status non-zero ہوتا ہے اور OpenSSL اس constraint کا نام بتاتا ہے جس سے ٹکراؤ ہوا۔ یہی extension کی افادیت ہے۔ چوری شدہ CA key بھی subtree سے باہر کے نام کے لیے ایسا certificate نہیں بنا سکتی جو عملی طور پر کام کرے۔ کام مکمل ہونے پر rm /tmp/outside.* سے باقی فائلیں حذف کریں۔
Constraint نافذ کرنے سے پہلے چار باتیں سمجھ لیں۔ اسے critical کے طور پر نشان زد کیا گیا ہے، اس لیے جو client اس extension کو نہیں سمجھتا اسے chain مسترد کرنی ہوگی، اسے نظرانداز نہیں کیا جا سکتا۔ یہ محفوظ رویہ ہے، لیکن پرانی TLS library کے لیے غیر متوقع ہو سکتا ہے۔ DNS names کے لیے permitted subtree، IP address SANs کو محدود نہیں کرتا، کیونکہ جس name type کے لیے subtree درج نہ ہو وہ غیر محدود رہتا ہے۔ اس لیے اگر آپ کے certificates میں IP addresses شامل ہوں تو اسی extension میں permitted;IP:10.0.0.0/255.255.0.0 بھی شامل کریں۔ Subtree میں ہر وہ نام شامل ہونا چاہیے جس کے لیے آپ کبھی certificate جاری کریں گے، جن میں short hostnames بھی شامل ہیں۔ اسی لیے bare name app کے لیے certificate اوپر دی گئی مثال کے مطابق ناکام ہو جائے گا۔ Constraint root میں مستقل طور پر شامل ہو جاتا ہے، اس لیے رائے بدلنے پر نیا root certificate بنانا اور ہر client پر اسے دوبارہ install کرنا پڑتا ہے۔
اپنے CA سے دستخط شدہ leaf certificate جاری کریں
leaf certificate وہ certificate ہے جو server کلائنٹس کو پیش کرتا ہے۔ پہلے اس کی اپنی key اور CSR (certificate signing request) بنائیں۔ CSR میں public key اور مطلوبہ نام شامل ہوتا ہے، اور leaf key اس پر دستخط کرتی ہے تاکہ ثابت ہو کہ درخواست دینے والے کے پاس private key موجود ہے۔
openssl req -new -newkey rsa:2048 -nodes \
-keyout app.key -out app.csr \
-subj "/CN=app.internal.example"
chmod 600 app.keyاہم نام extension file میں شامل کریں، CSR میں نہیں۔ کلائنٹس hostname کا مقابلہ subjectAltName (SAN) سے کرتے ہیں اور common name کو مکمل طور پر نظرانداز کرتے ہیں۔ اس لیے CN موجود ہو لیکن SAN نہ ہو تو موجودہ ہر client میں hostname verification ناکام ہو جاتی ہے، چاہے CN میں کچھ بھی لکھا ہو۔
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = DNS:app.internal.example, DNS:api.internal.example
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:alwaysاسے app.ext کے نام سے محفوظ کریں، پھر CA سے request پر دستخط کریں۔
openssl x509 -req -in app.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-days 397 -sha256 -extfile app.ext -out app.crt-CAcreateserial CA کے ساتھ ca.srl لکھتا ہے۔ اس file میں اگلا serial number محفوظ ہوتا ہے، تاکہ اس CA سے جاری ہونے والے کسی بھی دو certificates کا serial number ایک جیسا نہ ہو۔ اس file کو CA directory میں رکھیں۔ -days 397 ایک انتخاب ہے، tool کی حد نہیں۔ یہاں مختصر validity periods public CA کے مقابلے میں زیادہ اہم ہیں، کیونکہ private CA میں revocation infrastructure موجود نہیں ہوتا۔ CRL اور OCSP responder موجود نہیں ہوتے، جب تک آپ خود انہیں نہ بنائیں۔ اس لیے افشا ہونے والی leaf key certificate کے expire ہونے تک استعمال کے قابل رہتی ہے۔
Trust store کو دیکھنے سے پہلے نتیجہ چیک کریں۔
openssl x509 -noout -subject -issuer -serial -dates -in app.crt
openssl x509 -noout -ext subjectAltName -in app.crtاب issuer line میں leaf کے بجائے CA کا نام درج ہے۔ SAN line ان ناموں کی فہرست دکھاتی ہے جن کے لیے یہ certificate valid ہے۔ client صرف اسی فہرست کے خلاف مقابلہ کرتا ہے، کسی اور چیز کے خلاف نہیں۔
واضح -CAfile استعمال کرتے ہوئے، کچھ بھی install کرنے سے پہلے تصدیق کریں
openssl verify -CAfile ca.crt app.crt
echo $?یہ صرف ایک مخصوص سوال کا جواب دیتا ہے: کیا app.crt، ca.crt میں موجود certificate تک chain بنتا ہے؟ اس سے یہ معلوم نہیں ہوتا کہ یہ machine کس چیز پر trust کرتی ہے، کیونکہ آپ نے command line پر OpenSSL کو root فراہم کیا ہے۔ یہاں failure certificates کا مسئلہ ہے، اس لیے آگے بڑھنے سے پہلے اسے درست کریں۔
اب machine سے پوچھیں۔
openssl verify app.crt
echo $?-CAfile کے بغیر OpenSSL اپنی built-in certificate directory استعمال کرتا ہے۔ openssl version -d وہ base directory دکھاتا ہے جسے آپ کی build استعمال کرتی ہے، اور Ubuntu پر اس کے اندر موجود certs directory، /etc/ssl/certs پر resolve ہوتی ہے۔ آپ کا root ابھی وہاں موجود نہیں، اس لیے verification ناکام ہوتی ہے: chain ایسے issuer تک پہنچتی ہے جسے store hold نہیں کرتا، اور تلاش کرنے کے لیے مزید کوئی جگہ باقی نہیں رہتی۔ exit status نوٹ کریں۔ یہی وہ چیز ہے جو اب سے دو steps بعد تبدیل ہوگی۔
openssl verify کے مقابلے میں کوئی حقیقی client بہتر test فراہم کرتا ہے، کیونکہ وہ chain کے ساتھ hostname بھی check کرتا ہے۔ certificate serve کریں اور اسے fetch کریں۔
openssl s_server -accept 8443 -cert app.crt -key app.key -www &
curl --resolve app.internal.example:8443:127.0.0.1 https://app.internal.example:8443/--resolve connection کو 127.0.0.1 پر بھیجتا ہے، جبکہ app.internal.example کی request برقرار رکھتا ہے، اس لیے SAN match ہوتا ہے اور واحد زیرِ غور سوال trust کا رہ جاتا ہے۔ curl ناکام ہو جاتا ہے اور وہ وجہ دکھاتا ہے جس کی بنا پر chain verify نہیں ہو سکی۔ مزید تفصیل کے لیے -v شامل کریں۔ test server کو running رہنے دیں۔
/usr/local/share/ca-certificates میں root نصب کریں
sudo cp ca.crt /usr/local/share/ca-certificates/example-internal-root.crt
sudo chmod 644 /usr/local/share/ca-certificates/example-internal-root.crt
sudo update-ca-certificatesیہ تفصیلات طے کرتی ہیں کہ یہ عمل بالکل کامیاب ہوگا یا نہیں:
- فائل نام کا اختتام
.crtپر ہونا چاہیے۔update-ca-certificatesmanual page کے مطابق/usr/local/share/ca-certificatesکے اندر ملنے والے.crtextension والے certificates شامل اور implicit طور پر trusted ہوتے ہیں۔root.pemیاroot.cerنام والی فائل کو بغیر کسی پیغام کے چھوڑ دیا جاتا ہے۔ - مواد PEM ہونا چاہیے۔ یہ وہ base64 block ہے جو
BEGIN CERTIFICATEاورEND CERTIFICATEلائنوں کے درمیان ہوتا ہے۔.crtنام دینے سے DER فائل binary ہی رہتی ہے اور اسے پڑھا نہیں جاتا۔ اسےopenssl x509 -inform DER -in ca.der -out ca.crtکے ذریعے convert کریں۔ - یہاں صرف root ہونا چاہیے۔ CA private key اور leaf certificate کا trust store میں کوئی مقام نہیں۔
update-ca-certificates بتاتا ہے کہ اس نے کتنے certificates شامل اور حذف کیے۔ اگر اس نے کوئی certificate شامل نہیں کیا تو وجہ extension یا file format ہے۔
اس پیغام پر انحصار کرنے کے بجائے system کی طرف سے تبدیلی کی تصدیق کریں۔
ls -l /etc/ssl/certs/$(openssl x509 -noout -subject_hash -in /usr/local/share/ca-certificates/example-internal-root.crt).0
grep -c 'BEGIN CERTIFICATE' /etc/ssl/certs/ca-certificates.crtپہلی command آپ کے certificate کے اپنے subject hash سے filename بناتی اور اسے list کرتی ہے۔ update-ca-certificates نے یہ symlink بنایا تھا، اور یہ اسی file کی طرف واپس اشارہ کرتا ہے جسے آپ نے نصب کیا ہے۔ دوسری command single-file bundle میں certificates کی تعداد گنتی ہے۔ اسے install سے پہلے بھی چلائیں تاکہ تعداد میں ایک کا اضافہ دیکھا جا سکے۔
جب آپ اس root کو دوسری machines پر copy کریں تو اسے install کرنے سے پہلے تصدیق کریں کہ copy مکمل اور درست پہنچی ہے۔ root certificate system کی ایسی file ہے جسے غلط حاصل کرنا سب سے زیادہ نقصان دہ ہو سکتا ہے، اس لیے اسے بھی کسی دوسری download کی طرح استعمال سے پہلے checksum سے verify کریں۔
سسٹم اسٹور کے خلاف دوبارہ تصدیق کریں
openssl verify app.crt
echo $?
curl --resolve app.internal.example:8443:127.0.0.1 https://app.internal.example:8443/وہی commands، وہی certificate files، لیکن نتیجہ مختلف ہے۔ app.crt میں کوئی تبدیلی نہیں ہوئی، اور server وہی ہے جسے آپ نے پہلے start کیا تھا۔ صرف یہ فرق ہے کہ root اب اس store میں موجود ہے جسے وہ clients پڑھتے ہیں، اس لیے chain مکمل ہو جاتی ہے۔ یاد رکھنے کے قابل طریقۂ کار یہ ہے: verification ایسے issuer کی تلاش ہوتی ہے جس پر client پہلے سے اعتماد کرتا ہے، اور CA install کرنے سے issuer اس جگہ شامل ہو جاتا ہے جہاں client تلاش کرتا ہے۔
kill %1 کے ذریعے test server روک دیں۔
/etc/ssl/certs میں اپنی فائل کیوں نہیں رکھنی چاہیے
/etc/ssl/certs تیار کردہ output ہے۔ update-ca-certificates اس میں اصل certificate files کی طرف واپس جانے والے symlinks بناتا ہے اور ان کے ساتھ مرکب bundle /etc/ssl/certs/ca-certificates.crt لکھتا ہے۔
آپ اس directory میں جو certificate دستی طور پر copy کرتے ہیں، اسے کوئی بھی چیز نہیں ڈھونڈ پاتی۔ OpenSSL کی directory lookup صرف ان files کو کھولتی ہے جن کے نام certificate کے subject hash پر مبنی ہوں، اس لیے myca.crt نام کی file اس کے لیے نظر نہیں آتی۔ Ubuntu پر curl bundle file پڑھتا ہے، اور bundle registered sources سے دوبارہ بنایا جاتا ہے، اس لیے آپ کی copy اس path میں بھی شامل نہیں ہوتی۔ update-ca-certificates --fresh چلانے سے directory کے symlinks حذف کرکے دوبارہ بنائے جاتے ہیں، اور اس عمل میں دستی طور پر بنائی گئی link بھی حذف ہو جاتی ہے۔
اس تقسیم کا دوسرا حصہ /usr/share/ca-certificates ہے، جو ca-certificates package سے تعلق رکھتا ہے اور /etc/ca-certificates.conf میں درج ہے۔ Package updates اسے دوبارہ لکھتی ہیں۔ /usr/local/share/ca-certificates مقامی administrator کے لیے مخصوص directory ہے، اس لیے باقی certificates manage کرنے والے package کے ہر upgrade کے بعد بھی آپ کا CA برقرار رہتا ہے۔
کون سے پروگرام system trust store کو نظر انداز کرتے ہیں
وہ root certificate انسٹال کرنے سے ہر وہ پروگرام درست ہو جاتا ہے جو OpenSSL سے درخواست کرتا ہے یا /etc/ssl/certs کو پڑھتا ہے۔ اس میں curl، wget، git، Python کا معیاری ssl module، اور Go کے پروگرام شامل ہیں، جو Linux پر system files پڑھتے ہیں۔ وہ runtimes جو اپنی certificate list ساتھ فراہم کرتے ہیں، اس تبدیلی سے متاثر نہیں ہوتے۔ کامیاب installation کے بعد زیادہ تر الجھن اسی وجہ سے پیدا ہوتی ہے۔
- Node.js compiled-in list استعمال کرتا ہے۔ اسے
NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/example-internal-root.crtکے ذریعے اپنے root certificate کی طرف متوجہ کریں۔ اسے process شروع ہونے سے پہلے environment میں set کریں، کیونکہ Node یہ variable startup کے وقت صرف ایک بار پڑھتا ہے۔ موجودہ Node releases میں system store پڑھنے کا option بھی موجود ہے؛node --help | grep -i system-caچلائیں تاکہ معلوم ہو سکے کہ آپ کے version میں یہ option ہے یا نہیں۔ - Python کی
requestslibrary،certifibundle استعمال کرتی ہے۔ اس process کے لیےREQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crtset کریں، یا call میںverify="/etc/ssl/certs/ca-certificates.crt"pass کریں۔pipبھی اسی وجہ سے--certقبول کرتا ہے۔ - Java ایک keystore پڑھتا ہے۔ Ubuntu پر
ca-certificates-javapackage،/etc/ca-certificates/update.d/کے تحت ایک hook انسٹال کرتا ہے۔ اس package کے موجود ہونے پرupdate-ca-certificatesJava keystore کو بھی refresh کر دیتا ہے۔ اس کے بغیر root certificate کوkeytool -importcertکے ذریعے import کریں۔ - Firefox اپنا الگ store رکھتا ہے اور
/etc/ssl/certsکو کبھی نہیں دیکھتا۔ اس کے certificate settings کے ذریعے certificate import کریں۔ Linux پر Chromium فی user ایک NSS database پڑھتا ہے۔ اسےlibnss3-toolspackage کےcertutilکے ذریعے edit کریں۔ - Containers اپنا الگ filesystem رکھتے ہیں، اس لیے host کا store ان کے اندر مؤثر نہیں ہوتا۔ root certificate کو image میں copy کریں اور build کے دوران
update-ca-certificatesچلائیں۔ اگر آپ کی services VPS پر Docker Compose کے تحت چلتی ہیں تو اس ضرورت کو منصوبہ بندی میں شامل کریں۔
جب کوئی program clean install کے بعد بھی certificate قبول نہ کرے تو مزید تبدیلی کرنے سے پہلے معلوم کریں کہ وہ کون سی files کھولتا ہے۔ strace -f -e trace=openat <command> 2>&1 | grep -i cert ایک براہ راست طریقہ ہے، اور یہ سوال ایک ہی run میں حل کر دیتا ہے۔
وقت کے ساتھ CA کو قابلِ استعمال رکھنا
کسی leaf certificate کو دوبارہ جاری کرنے کے لیے CSR کا مرحلہ اور signing کا مرحلہ دوبارہ انجام دیں، اور وہی app.ext file استعمال کریں۔ Clients کو کوئی کارروائی کرنے کی ضرورت نہیں، کیونکہ ان کا trusted root تبدیل نہیں ہوا۔ ca.srl اور ہر .ext file کو CA directory میں محفوظ رکھیں، تاکہ اگلی بار certificate جاری کرنا یادداشت سے دوبارہ configuration بنانے کے بجائے پہلے سے کام کرنے والی command کو دہرانا ہو۔
ca.key اور ca.crt کا backup مشین سے باہر کسی مقام پر رکھیں اور اسے encrypted ہی رکھیں۔ اگر key ضائع ہو جائے تو آپ کچھ نیا issue نہیں کر سکتے۔ آپ کو دوسرا CA بنانا ہوگا اور اس کا root ہر اس جگہ install کرنا ہوگا جہاں پہلے CA کا root موجود تھا۔ ہر machine اور ہر application store کی تحریری فہرست رکھیں جہاں root install کیا گیا ہے، کیونکہ rotation اور removal اسی فہرست کی مدد سے ممکن ہوتے ہیں۔
جب root خود expiry کے قریب پہنچے تو replacement پہلے تیار کریں اور دونوں roots کو ساتھ ساتھ install کریں۔ Store میں دو roots کا ہونا مسئلہ نہیں، اور client ان میں سے کسی ایک کو قبول کر لیتا ہے۔ نئے root کے خلاف leaf certificates دوبارہ issue کریں، پھر پرانا root اس وقت remove کریں جب کوئی چیز اس پر منحصر نہ رہے۔
اعتماد اسٹور سے CA ہٹائیں
sudo rm /usr/local/share/ca-certificates/example-internal-root.crt
sudo update-ca-certificates --fresh--fresh، /etc/ssl/certs میں موجود symbolic links ہٹا کر انہیں ان sources سے دوبارہ بناتا ہے جو اب بھی موجود ہیں۔ اس طرح حذف شدہ root، directory اور bundle دونوں سے خارج ہو جاتا ہے۔ Removal کو اسی طریقے سے ثابت کریں جس طرح installation کو ثابت کیا تھا۔
openssl verify app.crt
echo $?
grep -c 'BEGIN CERTIFICATE' /etc/ssl/certs/ca-certificates.crt
ls -l /etc/ssl/certs/$(openssl x509 -noout -subject_hash -in ~/ca/ca.crt).0Verification دوبارہ ناکام ہو جاتی ہے، certificates کی تعداد ابتدائی تعداد پر واپس آ جاتی ہے، اور hash symlink ختم ہو جاتا ہے۔
یہ command صرف system store کو متاثر کرتا ہے، کسی اور جگہ کو نہیں۔ باقی ہر جگہ سے installation کو دستی طور پر واپس لیں: NODE_EXTRA_CA_CERTS صاف کریں، ہر Java keystore سے alias حذف کریں، ہر browser profile سے root ہٹائیں، اور ہر ایسی container image دوبارہ بنائیں جس میں یہ root شامل کیا گیا ہو۔ Root ہٹانے سے اس کے دستخط شدہ certificates بھی invalid نہیں ہوتے۔ ہر اس machine پر وہ valid رہتے ہیں جو اب بھی اس CA پر اعتماد کرتی ہے۔ اسی لیے private CA کے لیے یہ تحریری فہرست ضروری ہے کہ root کہاں کہاں شامل کیا گیا تھا۔ جس CA کو مکمل طور پر واپس نہیں لیا جا سکتا، وہ مستقل security hole بن جاتی ہے۔ اس لیے setup کے دن ہی ایک machine پر removal کی آزمائش کریں، جب فہرست ابھی مختصر ہو۔
FAQ
Ubuntu میں CA certificate کہاں رکھوں؟
اسے /usr/local/share/ca-certificates/ میں رکھیں۔ فائل کا نام .crt پر ختم ہونا چاہیے اور اس میں PEM مواد ہونا چاہیے۔ اس کے بعد sudo update-ca-certificates چلائیں۔ یہ directory مقامی administrator کے لیے مخصوص ہے، اس لیے package upgrades اسے تبدیل نہیں کرتے۔ /usr/share/ca-certificates، ca-certificates package سے تعلق رکھتی ہے، اور /etc/ssl/certs دونوں سے generate ہوتی ہے۔ اس لیے ان میں سے کسی directory میں رکھی گئی فائل overwrite یا ignore ہو سکتی ہے۔
update-ca-certificates کے بعد بھی curl certificate کیوں مسترد کرتا ہے؟
وجوہات کو اسی ترتیب سے جانچیں۔ ممکن ہے فائل کا نام .crt پر ختم نہ ہوتا ہو، یا certificate PEM کے بجائے DER format میں ہو۔ ایسی صورت میں update-ca-certificates اسے skip کر دیتا ہے اور کچھ شامل نہیں کرتا۔ ممکن ہے certificate میں hostname سے مطابقت رکھنے والا subjectAltName موجود نہ ہو۔ یہ trust failure کے بجائے hostname failure ہے؛ اسے openssl x509 -noout -ext subjectAltName -in app.crt سے جانچیں۔ ممکن ہے server صرف leaf certificate بھیج رہا ہو، حالانکہ intermediate certificate بھی درکار ہو۔ ممکن ہے curl کو CURL_CA_BUNDLE یا --cacert کے ذریعے کسی دوسرے bundle کی طرف بھیجا گیا ہو۔ طویل عرصے سے چلنے والی service کو restart بھی کرنا ہوگا، کیونکہ زیادہ تر programs start ہوتے وقت trust store صرف ایک بار پڑھتے ہیں۔
کیا system trust store Firefox، Chrome، Node اور Java کے لیے کافی ہے؟
نہیں۔ curl، wget، git، Python کا standard ssl module اور Go programs system files پڑھتے ہیں، اس لیے update-ca-certificates چلتے ہی یہ کام کرنے لگتے ہیں۔ Firefox اپنا الگ store رکھتا ہے۔ Linux پر Chromium فی user ایک NSS database استعمال کرتا ہے، جسے libnss3-tools package کے certutil سے edit کیا جاتا ہے۔ Node.js کے لیے NODE_EXTRA_CA_CERTS کو آپ کی root file کی طرف point کرنا ضروری ہے۔ Java ایک keystore پڑھتا ہے، جسے update-ca-certificates صرف اس وقت refresh کرتا ہے جب ca-certificates-java package installed ہو۔ Python کا requests certifi استعمال کرتا ہے اور اسے REQUESTS_CA_BUNDLE درکار ہے۔
Ubuntu کے trust store سے CA کیسے ہٹاؤں؟
فائل /usr/local/share/ca-certificates/ سے delete کریں اور sudo update-ca-certificates --fresh چلائیں۔ --fresh option، /etc/ssl/certs میں موجود symlinks صاف کرکے انہیں دوبارہ بناتا ہے۔ اس طرح certificate hash symlinks اور ca-certificates.crt bundle، دونوں سے بیک وقت ہٹ جاتا ہے۔ اس کی تصدیق کے لیے openssl verify کو اس certificate کے خلاف چلائیں جسے اس CA نے sign کیا ہو، اور exit status پڑھیں۔ اس کے بعد ہر دوسرے store سے بھی اسے ہٹائیں جہاں آپ نے یہ certificate شامل کیا تھا، کیونکہ یہ command ان stores کو نہیں چھیڑتی۔
کیا public site کے لیے Let's Encrypt کے بجائے private CA استعمال کر سکتا ہوں؟
نہیں۔ visitor کے browser نے آپ کی root پہلے کبھی نہیں دیکھی، اس لیے وہ پورے صفحے کی warning دکھائے گا۔ آپ اپنی root ان machines پر install نہیں کر سکتے جنہیں آپ control نہیں کرتے۔ private CA ان names کے لیے ہے جنہیں صرف آپ کی اپنی machines resolve کرتی ہیں، اور ان clients کے لیے ہے جنہیں آپ administer کرتے ہیں۔ جس site پر عام visitor آتے ہوں، اس کے لیے certificate کسی public CA سے حاصل کریں۔