SSD Nodes Learn Hosting plans →
নির্দেশিকা Matt Connorদ্বারা Matt Connor

Reproducible build কী প্রমাণ করে, checksum কী নয়

Checksum শুধু ডাউনলোড করা ফাইল অক্ষত এসেছে কি না জানায়। Reproducible build প্রমাণ করে binary-টি পড়তে পারা একই source code থেকে তৈরি, তাই দুই দাবির পার্থক্য বুঝুন।

পুনরুৎপাদনযোগ্য build কী প্রমাণ করে

পুনরুৎপাদনযোগ্য build একটি নির্দিষ্ট বিষয় প্রমাণ করে: আপনাকে দেওয়া binary-টি এই নির্দিষ্ট source code থেকেই তৈরি হয়েছে। একই source নিয়ে যে কেউ আবার build করতে এবং byte তুলনা করতে পারে। ফলে verification আর শুধু publisher-এর পক্ষে করা সম্ভব থাকে না।

Reproducible Builds project এটি সংজ্ঞায়িত করেছে এভাবে: "একই source code, build environment এবং build instructions দেওয়া হলে যেকোনো পক্ষ যদি নির্দিষ্ট সব artifact-এর bit-by-bit অভিন্ন copy পুনরায় তৈরি করতে পারে, তবে সেই build reproducible।" তুলনাটি নিজেই একটি hash। মূল কঠিন কাজ হলো environment এবং instructions এত কঠোরভাবে নির্দিষ্ট করা, যাতে দুটি ভিন্ন machine একই ফল দেয়।

কেন checksum এই প্রশ্নের উত্তর দেয় না

প্রকাশিত checksum প্রমাণ করে যে আপনি যে ফাইলটি ডাউনলোড করেছেন, সেটি reference value-এর সঙ্গে মিলে যায়। অর্থাৎ ফাইলটি corruption ছাড়াই পৌঁছেছে। কিন্তু ফাইলটি কে তৈরি করেছে, checksum সে বিষয়ে কিছু বলে না। Apache-এর verification guide hash সম্পর্কে স্পষ্টভাবে বলে: "এগুলো ফাইলটির authenticity সম্পর্কে কোনো নিশ্চয়তা দেয় না।" Reference checksum এমন একটি উৎস থেকে আসতে হবে, যাকে আপনি বিশ্বাস করতে পারেন। তা না হলে checksum মিলে গেলেও কোনো প্রমাণ হয় না। সেই checksum-এর ওপর করা signature প্রমাণ করে যে এটি key-ধারী ব্যক্তির কাছ থেকে এসেছে, তবে আগে আপনাকে যাচাই করতে হবে যে key-টি সত্যিই publisher-এর। Artifact তৈরি হওয়ার আগের ঘটনাগুলো সম্পর্কে কোনোটিই কিছু বলে না। Publisher-এর build machine compromised হলে malicious binary-ও clean binary-এর মতোই checksum করা এবং signed হয়। ফলে পরবর্তী প্রতিটি check সফল হয়। কোনো maintainer এমন working tree থেকে build করলেও একই ঘটনা ঘটে, যা কখনো repository-তে push করা হয়নি।

এটাই সেই ঘাটতি। আপনি source পড়তে, signature verify করতে এবং checksum verify করতে পারেন। তবু এমন code চালাতে পারেন, যা repository-তে কখনো প্রকাশিত হয়নি। তাই reproducibility এবং প্রকাশিত checksum-এর সঙ্গে download যাচাই করা আলাদা বিষয়। Checksum transfer সুরক্ষিত করে। Rebuild transfer-এর আগের সব ঘটনাকে সুরক্ষিত করে।

এই attack কেবল তাত্ত্বিক নয়। 2020 সালের SolarWinds Orion compromise ঠিক এই অবস্থানেই ঘটেছিল: build system এমন signed artifact তৈরি করেছিল, যা কেউ review করা source-এর সঙ্গে মিলত না। প্রতিটি signature check সফল হয়েছিল, কারণ signature-এর শুরু artifact থেকেই।

পুনরুৎপাদনযোগ্য build যা প্রমাণ করে না

এই বিষয়টি প্রায়ই অতিরঞ্জিতভাবে উপস্থাপন করা হয়। তাই সীমাবদ্ধতাগুলো স্পষ্টভাবে বুঝুন।

  • এটি প্রমাণ করে না যে source নিরাপদ। প্রকাশ্যভাবে যোগ করা একটি backdoor reproducibly build হতে পারে, এবং প্রতিটি rebuilder সেটি নিশ্চিত করতে পারে, কারণ সবাই একই ক্ষতিকর source build করেছে। Reproducibility-এর ফলে যাচাইয়ের লক্ষ্য source tree-তে স্থানান্তরিত হয়। সেই tree এখনও কাউকে পড়ে পরীক্ষা করতে হবে। এ কারণেই open source project-এ AI-assisted code ব্যবহারের policy আলাদা control হিসেবে থাকে।
  • এটি প্রমাণ করে না যে আপনার input নিরাপদ। আপনি যা build করেন, তার অংশ dependency-ও। Build-এর সময় resolve করা একটি ক্ষতিকর package artifact-এর মধ্যে compile হয়ে যায়। একই dependency resolve করা প্রতিটি rebuilder আপনার সঙ্গে একই ফলাফলে সম্মত হবে। এভাবেই একটি npm supply chain attack server-এ পৌঁছায়, এবং reproducible build সেটিই সঠিকভাবে পুনরুৎপাদন করে।
  • এটি প্রমাণ করে না যে toolchain নির্ভরযোগ্য। Compiler compromised হলে, সেটি ব্যবহার করা প্রতিটি rebuilder একই compromised output তৈরি করবে এবং সব verdict একমত হবে। Reproducibility এই আক্রমণের খরচ বাড়ায়। কিন্তু এটি আক্রমণ শনাক্ত করে না।
  • Vulnerability সম্পর্কে এটি কিছুই বলে না। Bit-for-bit reproducible একটি পুরোনো library তবুও প্রকাশিত flaw-সহ পুরোনো library-ই থাকে। তাই আপনার server-এ পরিচিত CVE আছে কি না তা পরীক্ষা করা নিজস্ব schedule অনুযায়ী চালিয়ে যান।

Reproducibility একটি নির্দিষ্ট attacker position সরিয়ে দেয়: build machine এবং source থেকে binary পর্যন্ত সম্পূর্ণ পথ। কোনো package reproducible না হওয়া পর্যন্ত publisher-এর বাইরের কেউই সেই পথ পরিদর্শন করতে পারে না।

একই source থেকে ভিন্ন byte কেন তৈরি হয়

বেশিরভাগ software ডিফল্টভাবে reproducible নয়, এবং কারণগুলো সাধারণ। Compiler ও archive format যে machine-এ চলে, সেই machine সম্পর্কিত তথ্য record করে।

  • একটি timestamp। tar, ar এবং zip format file-এর modification time সংরক্ষণ করে। তাই ভিন্ন second-এ build করলে output file পরিবর্তিত হয়।
  • একটি path। Debug information absolute build directory record করে। তাই code একই হলেও /home/alice/src-এ build এবং /build/pkg-এ build ভিন্ন হয়।
  • একটি ordering। Directory পড়লে entry-গুলো filesystem order-এ ফেরত আসে। তাই machine ভেদে link line বা archive member-এর order পরিবর্তিত হয়।
  • একটি identity। Build script যে user build করেছে তার username, hostname বা locale embed করে।
  • Build time-এ নেওয়া একটি সিদ্ধান্ত। CPU feature শনাক্ত করা বা কোনো কিছু randomভাবে seed করা হলে output source-এর বদলে machine-এর ওপর নির্ভর করে।

প্রথম কারণটি প্রায় দশ সেকেন্ডে দেখা যায়:

mkdir -p /tmp/rb && cd /tmp/rb
echo hello > a.txt && tar cf one.tar a.txt
sleep 2
echo hello > a.txt && tar cf two.tar a.txt
sha256sum one.tar two.tar

দুটি hash আলাদা, কারণ tar header a.txt-এর modification time সংরক্ষণ করে। File rewrite করার ফলে সেই time দুই second এগিয়ে গেছে। Content byte for byte একই। Metadata নির্দিষ্ট করে দিলে সমস্যাটি ঠিক হয়:

export SOURCE_DATE_EPOCH=1700000000
tar --sort=name --mtime="@${SOURCE_DATE_EPOCH}" --owner=0 --group=0 --numeric-owner -cf three.tar a.txt
touch a.txt
tar --sort=name --mtime="@${SOURCE_DATE_EPOCH}" --owner=0 --group=0 --numeric-owner -cf four.tar a.txt
sha256sum three.tar four.tar

এখন hash মিলে যায়, কারণ archive header-এর কোনো field machine-এর বর্তমান অবস্থা থেকে আসে না। --sort=name ordering নির্দিষ্ট করে, --mtime clock নির্দিষ্ট করে, এবং ownership flag আপনার user id record হওয়া বন্ধ করে।

diffoscope-এর পার্থক্য বিশ্লেষণ

দুটি build-এর মধ্যে পার্থক্য থাকলে, sha256sum শুধু জানায় যে তারা আলাদা। পার্থক্যের কারণ জানায় না। মানুষ পড়তে পারে এমন ভাষায় কারণ ব্যাখ্যা করার জন্য diffoscope ব্যবহার করা হয়। এটি উভয় দিকের বিষয়বস্তু recursive পদ্ধতিতে unpack করে, binary format-কে text-এ রূপান্তর করে এবং সেই text-এর diff তৈরি করে। এটি Debian package, ELF binary, tar ও ZIP archive, PDF, SQLite database এবং আরও ডজনখানেক format সমর্থন করে।

sudo apt install -y diffoscope
diffoscope one.tar two.tar

উপরের tar জোড়ার জন্য report সংক্ষিপ্ত। সংক্ষেপে এটি এমন দেখায়:

--- one.tar
+++ two.tar
├── file list
│ @@ -1 +1 @@
│ -rw-r--r-- 0/0  6 2026-08-18 10:14:02.000000 a.txt
│ +rw-r--r-- 0/0  6 2026-08-18 10:14:04.000000 a.txt

এটাই সম্পূর্ণ diagnosis: size একই, path একই, permission একই, কিন্তু modification time আলাদা। বাস্তব package-এর report অনেক দীর্ঘ হয়। তাই report-টি file-এ লিখে browser-এ খুলুন:

diffoscope --html report.html build1.changes build2.changes

Input একই হলে diffoscope 0 exit code দেয়, পার্থক্য থাকলে 1 দেয় এবং কোনো সমস্যা হলে 2 দেয়। তাই কোনো wrapper script ছাড়াই এটি সরাসরি CI job-এ ব্যবহার করা যায়। ছোট VPS-এ diffoscope-এর পরিবর্তে diffoscope-minimal install করুন। Full package-টি এমন অনেক format helper install করে, যেগুলোর অধিকাংশই আপনার প্রয়োজন হবে না।

SOURCE_DATE_EPOCH কী ঠিক করে এবং কোথায় এর সীমা

SOURCE_DATE_EPOCH হলো একটি environment variable, যাতে একটি সংখ্যা থাকে: source-এর সর্বশেষ modification time, 1 January 1970 UTC থেকে অতিবাহিত seconds হিসেবে গণনা করা। যে build tool এটি সমর্থন করে, সেটি operating system-এর কাছ থেকে বর্তমান সময় নেওয়ার পরিবর্তে যেখানে প্রয়োজন সেখানে এই সংখ্যা ব্যবহার করে। এটি version control থেকে সেট করুন, যাতে মানটি build-এর পরিবর্তে source অনুসরণ করে:

export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)

Debian package-এ debhelper changelog থেকে SOURCE_DATE_EPOCH নিজেই export করে। debian/rules-এ হাতে সেট করলে তা এভাবে লিখতে হয়:

export SOURCE_DATE_EPOCH ?= $(shell dpkg-parsechangelog -STimestamp)

প্রতিটি tool-এর support আলাদা; এটি global নয়। cmake 3.8 এবং পরবর্তী version, gcc 7 এবং পরবর্তী version, rpm 4.13-এর পরের version এবং Docker buildx 0.10 ও পরবর্তী version এটি পড়ে। আপনি নিজে script-এ ব্যবস্থা না করলে আপনার script এটি ব্যবহার করবে না। কোনো script যদি date call করে, তাহলে variable-টি তাকে দিন:

BUILD_DATE="$(date --utc --date="@${SOURCE_DATE_EPOCH:-$(date +%s)}" +%Y-%m-%d)"

বাস্তবায়নের সময় একটি নিয়ম গুরুত্বপূর্ণ। Variable-টি আগে থেকেই set করা থাকলে build-এর দৃষ্টিতে ওই মানটিই বর্তমান সময়। তাই clock পড়ার পরিবর্তে যেখানে সময় দরকার সেখানে এই মান ব্যবহার করুন এবং build যে প্রতিটি process শুরু করে, সেগুলোর জন্য variable-টি set অবস্থায় রাখুন। specification-এ বিষয়টি স্পষ্টভাবে বলা হয়েছে: "Build processes MUST NOT unset this variable for child processes if it is already present."

Container image-এ একই সমস্যা ভিন্ন wrapper-এর মাধ্যমে দেখা যায়। Docker buildx 0.10 এবং পরবর্তী version আপনার shell থেকে SOURCE_DATE_EPOCH-কে build argument হিসেবে build-এর মধ্যে পাঠায়। Layer-এর ভিতরের file-গুলোর timestamp পরিবর্তন করতে exporter-এর সেগুলো rewrite করা প্রয়োজন। BuildKit 0.13-এ এই support যোগ করেছে, এবং নথিভুক্ত পদ্ধতিতে ফলাফল registry-তে push করা হয়:

export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
docker buildx build --output type=image,name=registry.example.com/app:1.0,push=true,rewrite-timestamp=true .

reprotest দিয়ে নিজের build পরীক্ষা

reprotest একই source দুবার build করে। দুইবারের মধ্যে ইচ্ছাকৃতভাবে environment পরিবর্তন করে। এরপর ফলাফল তুলনা করে। এই variation-গুলোই পরীক্ষার মূল উদ্দেশ্য। ডিফল্টভাবে এটি environment variable, build path, kernel version, address space randomisation, CPU-এর সংখ্যা, সময়, user ও group, file ordering, domain ও host name, home directory, locale, executable path, timezone এবং umask পরিবর্তন করে।

sudo apt install -y reprotest
reprotest . -- null

---এর পরের সবকিছু build environment backend নির্বাচন করে। null বলতে আপনি যে system-এ কাজ করছেন সেটিকে বোঝায়। পরিদর্শনের জন্য temporary directory রেখে দিতে -vv -d যোগ করুন, যেমন reprotest . -vv -- null -d-এ দেখানো হয়েছে। source tree-এর ধরন স্বয়ংক্রিয়ভাবে শনাক্ত করতে reprotest auto -- null ব্যবহার করুন।

কিছু variation-এর জন্য অতিরিক্ত privilege বা package প্রয়োজন। এগুলো চালানো সম্ভব না হলে reprotest স্পষ্টভাবে ব্যর্থতার বার্তা দেখায়। পুরো কাজটি root হিসেবে চালানোর বদলে এই variation-গুলো বন্ধ করুন:

reprotest --vary=-user_group,-domain_host,-fileordering auto -- null

reprotest যে কোনো সমস্যা জানালে বুঝতে হবে, কোনো rebuilder পরে সেটিই publicভাবে জানাতে পারত এবং সেখানে আপনার project-এর নাম উল্লেখ থাকত।

Rebuilder-এর verdict-এর অর্থ

Rebuilder হলো এমন একটি machine, যা publisher-এর machine নয়। এটি প্রকাশিত source এবং নথিভুক্ত build environment ব্যবহার করে package আবার build করে। এরপর নিজের output archive-এর artifact-এর সঙ্গে তুলনা করে। এই verdict-এর মূল্য আছে শুধু এই কারণে যে machine-টি independent।

Debian একটি .buildinfo file-এ environment নথিভুক্ত করে। dpkg-buildpackage এই file-টি .deb-এর পাশে লেখে। এই file-এর field-গুলোই গুরুত্বপূর্ণ। Installed-Build-Depends build-কে প্রভাবিত করতে পারে এমন প্রতিটি installed package-এর exact version-সহ তালিকা দেয়। Build-Path build কোথায় চালানো হয়েছিল তা নথিভুক্ত করে। Environment যেসব environment variable গুরুত্বপূর্ণ বলে জানা আছে, সেগুলো নথিভুক্ত করে। Checksums-Sha256 output-সংক্রান্ত তথ্য রাখে। দ্বিতীয়বার build করার recipe হলো এই file:

sudo apt install -y devscripts mmdebstrap
debrebuild --buildresult=./artifacts --builder=mmdebstrap hello_2.10-2_amd64.buildinfo

debrebuild buildinfo পড়ে এবং সেখানে উল্লেখ করা exact dependency version-গুলো snapshot.debian.org থেকে সংগ্রহ করে। ফলে আজ rebuild করলেও original build-এর দিনের package version ব্যবহার করা যায়। mmdebstrap builder-এর chroot setup বা superuser rights দরকার হয় না। এটি যে artifact তৈরি করে, সেগুলো archive-এর copy-এর সঙ্গে diffoscope ব্যবহার করে তুলনা করুন।

Arch Linux rebuilderd চালায়। এটি ধারাবাহিকভাবে এই কাজ করে এবং verdict প্রকাশ করে:

rebuildctl -H https://reproducible.archlinux.org pkgs ls --name rebuilderd

Status হলো GOOD, BAD এবং UNKWN। প্রতিটির সরল অর্থ ভিন্ন ধরনের ভুল ধারণা তৈরি করতে পারে। GOOD-এর অর্থ হলো independent কোনো পক্ষ একই byte পেয়েছে। এটি build সম্পর্কে শক্তিশালী প্রমাণ দেয়, কিন্তু source সম্পর্কে কোনো প্রমাণ দেয় না। BAD প্রায় কখনোই attack-এর ফল নয়। সাধারণ কারণ হলো এমন timestamp বা path, যা packaging প্রক্রিয়া নির্দিষ্টভাবে স্থির করেনি। তাই rebuilderd failure-এর সঙ্গে diffoscope report যুক্ত করতে পারে। UNKWN-এর অর্থ হলো কেউ এটি পরীক্ষা করেনি। পরীক্ষা না করা package-কে passing package বলা যায় না।

তাই operational rule সংক্ষিপ্ত। BAD verdict পেলে report পড়ুন। Report-এ timestamp, build path বা member ordering দেখা গেলে packaging bug report করুন। এসবের কোনো ব্যাখ্যা ছাড়াই ভিন্ন executable code দেখা গেলে ওই build deploy করা বন্ধ করুন এবং বিষয়টি escalate করুন।

Debian এখন কতটা reproducible?

চার্টDebian packages reproducible in the test framework, amd64
এই চার্টের পেছনের ডেটা
[
  {
    "label": "unstable",
    "percent_reproducible": 94.8,
    "tested_count": "41,490"
  },
  {
    "label": "forky",
    "percent_reproducible": 95.7,
    "tested_count": "39,529"
  },
  {
    "label": "experimental",
    "percent_reproducible": 72.5,
    "tested_count": "619"
  }
]

2026-10-15 তারিখে amd64-এর unstable শাখায় পরীক্ষা করা 41,490টি প্যাকেটের মধ্যে 94.8% reproducible ছিল। Experimental শাখায় এই হার ছিল 72.5%। সেখানে নমুনা ছিল অনেক ছোট এবং অনেক নতুন 619টি প্যাকেটের। যেসব প্যাকেটের সংশোধন এখনো সম্পূর্ণ হয়নি, তাদের ক্ষেত্রে এটিই স্বাভাবিক।

এই পরিসংখ্যান নেওয়া হয়েছে tests.reproducible-builds.org-এর Debian পৃষ্ঠা থেকে। পৃষ্ঠাটি 2026-10-15 তারিখে পড়া হয়েছিল, এবং সেখানে "Last update: 2026-10-15 13:02 UTC" লেখা ছিল। এই সংখ্যা পরিবর্তিত হয়। ছয় মাস পর এই অনুচ্ছেদ উদ্ধৃত না করে tracker দেখুন।

শতাংশের চেয়েও গুরুত্বপূর্ণ একটি সতর্কতা আছে। এই framework প্রতিটি প্যাকেট একই hardware-এ দুবার build করে। দুইবারের build-এর মধ্যে environment পরিবর্তন করা হয়, তারপর framework নিজের তৈরি দুই ফলাফল তুলনা করে। এতে মাপা হয় কোনো প্যাকেট reproducibly build করা সম্ভব কি না। archive-এ থাকা .deb-এর সঙ্গে ফলাফল মেলে কি না, এটি তার যাচাই নয়। সেই কাজটি আলাদা rebuilder করে, যা published artifact-এর সঙ্গে তুলনা করে। উভয় সংখ্যাই কার্যকর। তারা ভিন্ন প্রশ্নের উত্তর দেয়, কিন্তু অনেকে প্রথম সংখ্যাটিকে দ্বিতীয়টি হিসেবে উদ্ধৃত করেন।

নিজের সার্ভারে কী করবেন

আপনাকে কোনো distribution পুনর্নির্মাণ করতে হবে না। সাধারণ সার্ভারে প্রয়োগযোগ্য পদক্ষেপগুলো কম এবং সাশ্রয়ী।

  • toolchain নির্দিষ্ট করে রাখুন। tag দিয়ে উল্লেখ করা base image আপনার অজান্তে পরিবর্তিত হতে পারে। digest দিয়ে image উল্লেখ করুন এবং release-এর সঙ্গে সেই digest সংরক্ষণ করুন।
  • input-গুলো নথিভুক্ত করুন। artifact-এর পাশে lockfile, image digest এবং compiler version রাখুন। যে build-এর environment পুনর্গঠন করা যায় না, সেটি পুনর্নির্মাণ করা যায় না। তাই সেটি কখনো যাচাইও করা যায় না।
  • CI-তে দুবার build করুন এবং output আলাদা হলে job ব্যর্থ করুন। এতে একটি অতিরিক্ত build লাগে। কেউ nondeterminism যোগ করার দিনই এটি তা শনাক্ত করে, কোনো incident-এর সময় এক বছর পরে নয়।
  • compiler যে path-গুলো binary-তে সংরক্ষণ করে, সেগুলো বাদ দিন। Go-এর ক্ষেত্রে go build -trimpath -buildvcs=false build directory এবং version control stamp সরিয়ে দেয়। go version -m ./app binary-তে বাস্তবে কী ঢুকেছে তা দেখায়।
  • যে artifact deploy করেছেন, তার hash সংরক্ষণ করুন। চলমান binary-টি কোনো source revision-এর সঙ্গে মেলে কি না জানতে হলে এই record-ই তার উত্তর দিতে পারে।

CI check-টি চার লাইনের:

set -eu
./build.sh && mv dist/app app.1
./build.sh && mv dist/app app.2
diffoscope --text - app.1 app.2

দুটি artifact আলাদা হলে diffoscope non-zero status দিয়ে শেষ হয়। তাই job নিজে থেকেই ব্যর্থ হয় এবং log-এ পড়ার উপযোগী ব্যাখ্যা রেখে যায়। একটি repository-তে এই ধারণাটির সংক্ষিপ্ত রূপ এটাই: কোনো binary source tree থেকে এসেছে—এই দাবিটি যেন দ্বিতীয় একটি machine যাচাই করতে পারে।

FAQ

পুনরুৎপাদনযোগ্য build কি software নিরাপদ—এমনটা বোঝায়?

না। এটি শুধু প্রমাণ করে যে binary-টি source-এর সঙ্গে সামঞ্জস্যপূর্ণ। এর বেশি কিছু নয়। public source tree-তে যুক্ত করা backdoor-ও reproducibly build হয়। কারণ প্রতিটি rebuilder একই ক্ষতিকর source থেকে build করেছে। পরিচিত CVE-যুক্ত package নিখুঁতভাবে reproduce হতে পারে এবং তবুও vulnerable থাকতে পারে। Reproducibility একটি attacker position দূর করে: build machine এবং source থেকে binary পর্যন্ত পথ। Source পড়া এবং vulnerability track করা আলাদা কাজ। Reproducibility এই কাজগুলো আপনার হয়ে করে না।

Source-এ কোনো পরিবর্তন না হলেও আমার দুটি build আলাদা হয় কেন?

প্রায় সব ক্ষেত্রেই কারণ হয় timestamp, path অথবা ordering। tar এবং zip-এর মতো archive format file modification time সংরক্ষণ করে। তাই ভিন্ন second-এ করা checkout ভিন্ন byte তৈরি করে। Debug information-এ absolute build directory সংরক্ষিত হয়। তাই একই code থেকে /home/alice/src এবং /build/pkg ভিন্ন binary তৈরি করে। Directory read করলে entry-গুলো filesystem order-এ ফেরত আসে। ফলে অন্য machine-এ link line-এর object file-এর order আলাদা হতে পারে। diffoscope build1 build2 চালান। এতে অনুমান না করে কোন কারণটি দায়ী, report-এ তা দেখা যাবে।

SOURCE_DATE_EPOCH কী এবং আমাকে কি এটি set করতে হবে?

এটি একটি standard environment variable। এতে একটি সংখ্যা থাকে: source-এর সর্বশেষ modification time, 1 January 1970 UTC থেকে elapsed second হিসেবে। যে tool এটি support করে, সেটি system clock পড়ার পরিবর্তে প্রয়োজনীয় স্থানে এই value ব্যবহার করে। Version control থেকে export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) দিয়ে এটি set করুন। এটি automatic নয় এবং সাধারণ সমাধানও নয়। শুধু যে tool এটি implement করেছে, সেটিই value-টি পড়ে। আপনার নিজের build script-কে এটি নিজে পড়তে হবে। তাই কোনো script date call করলে, পরিবর্তন না করা পর্যন্ত সেটি current time stamp করতে থাকবে।

কোনো rebuilder BAD report করলে আমার কী করা উচিত?

অন্য কিছু করার আগে report পড়ুন। BAD verdict-এর অর্থ হলো একটি independent rebuild একই byte তৈরি করেনি। সাধারণ কারণ attack নয়, packaging-এর nondeterminism। এই কারণেই rebuilderd diffoscope report তৈরি করতে পারে। পার্থক্য যদি timestamp, build path অথবা file ordering-এ হয়, তবে এটি filing করার মতো packaging bug। কোনো ব্যাখ্যা ছাড়াই executable code-এ পার্থক্য থাকলে সেই build deploy করা বন্ধ করুন, artifact-গুলো সংরক্ষণ করুন এবং publisher-এর কাছে বিষয়টি escalate করুন।

এই লেখাটি কি কাজে লেগেছে?

#reproducible-builds#supply-chain#diffoscope#debian#verification