Derleyicilerden nefret ediyorum
(xeiaso.net)- Anubis, web sitesi koruması için proof-of-work yaklaşımını SHA-256'nın ötesine taşırken, istemci ve sunucunun aynı WebAssembly doğrulama mantığını çalıştıracağı şekilde tasarlanıyor
- WebAssembly'nin kapalı olduğu ortamları da dışlamamak için JavaScript yeniden derleme yolu hazırlandı; ancak bu yol WebAssembly'den daha yavaş ve JIT de kapalıysa daha da yavaş olabilir
- Linux dağıtımlarındaki
wasm2jseski kaldığı için Homebrew sürümüyle çıktılar farklılaştı; yeniden üretilebilir derlemeler için wasi-sdk ile derlenmişwasm2jspaketle birlikte sunulmaya başlandı - C/C++ derlemelerinde
__DATE__,__TIME__,$PATHiçindekiwasm-optve istisna işleme kodundaki işaretçi sırası yüzünden aynı girdide bile bayt düzeyinde çıktı değişebilir - Nihai uygulama,
--no-wasm-opt,setarch --addr-no-randomize, x86_64 ve arm64 için SHA-256 doğrulaması ve CI yeniden derleme kontrolleriyle mimari içi determinizm sağlıyor
Anubis'in WebAssembly proof-of-work'ü ve JavaScript yedek yolu
- Anubis, yöneticilerin web sitesi korumasında SHA-256 dışında bir proof-of-work yöntemi kullanabilmesi için WebAssembly tabanlı proof-of-work doğrulaması eklemeyi planlıyor
- Temel hedef, doğrulama mantığını istemci ve sunucu için ayrı ayrı uygulamak yerine tek bir yerde tanımlamak
- İstemci ve sunucu, doğrulama mantığını çalıştırmak için aynı WebAssembly'ye bağlanıyor
- Her iki tarafın da lockstep içinde çalıştığını doğrulayan bir yapı hedefleniyor
- WebAssembly'nin kapalı olduğu istemciler de hesaba katılıyor
- Kullanıcıları fiilen web sitesinden dışlamak istenmiyor
- Anubis, kullanıcı deneyimi, yönetici deneyimi ve geliştirici deneyimi arasında denge kurmak zorunda
- Seçilen geçici çözüm, WebAssembly'yi yeniden JavaScript'e derlemek
- İlham kaynağı The Birth and Death of JavaScript
- Ortaya çıkan JavaScript, eşdeğer WebAssembly'den daha yavaş
- WebAssembly devre dışı bırakıldığında, JavaScript JIT'in de birlikte kapanabildiği durumlar var; bu da daha fazla yavaşlamaya yol açabiliyor
- Düşük donanımlı sistemlerde bunun mevcut JavaScript'ten daha verimli olup olmadığı için ek araştırma gerekiyor
wasm2js neden paketlenmek zorunda kaldı
- Gerekli araç, binaryen projesindeki
wasm2js wasm2js, Linux dağıtımlarında paket olarak bulunuyor; ancak dağıtım sürümü eski kaldığı için geliştirme ortamındaki Homebrew sürümüyle aynı çıktıyı üretemedi- Yeniden üretilebilir derlemeler için çıktının deterministik olması şart
- Anubis deposuna commit edilen
wasm2jsikilisine kullanıcıların ve paketleyicilerin güvenebilmesi için, aynı sürümü kendileri de derleyip aynı baytları elde edebilmesi gerekiyor - Mümkünse farklı kişilerin makinelerinde de aynı baytlar çıkmalı
- Anubis deposuna commit edilen
- Bunun için
wasm2js'nin, wasi-sdk ile WebAssembly hedefi için derlenmiş bir kopyası depoya dahil ediliyor
C/C++ derlemelerinde yeniden üretilebilirliğin kolayca bozulduğu noktalar
- Aynı kaynak baytları ve aynı girdi verilse bile derleyici çıktısı her zaman aynı baytları üretmeyebilir
- C/C++ tarafında yalnızca
__DATE__ve__TIME__gibi yerleşik makrolar bile deterministik olmayan çıktıya neden olabilir- Örnek
hello.cpp, derleme anındaki tarih ve saati yazdıracak şekilde hazırlanmış - Bir derleme
Jun 18 2026 00:00:59, bir diğeri iseJun 18 2026 00:01:11çıktısı verdi - Kaynak kod aynı baytlardı, ancak derleyici çıktısı farklıydı
- Örnek
- Küçük ölçekli bir derleyici teorik olarak deterministik olabilir; ancak gerçek dünyadaki derleyicilerde çok daha karmaşık değişkenler bulunuyor
Clang'ın $PATH içindeki wasm-opt'u sessizce çalıştırması sorunu
- binaryen,
wasm2jsdışında WebAssembly derleyici çıktısını optimize edenwasm-optaracını da içeriyor - Clang, derleme sırasında
wasm-opt'u shell out ile çalıştırıyor- Normalde bu, performans iyileştirmesi için makul bir davranış
- Ancak bu vakada,
$PATHiçindekiwasm-optsürüm farkı yeniden üretilebilirliği bozdu
- DGX Spark üzerindeki
wasm-opt,/usr/bin/wasm-optsürüm 108'di; iş istasyonundaki Homebrewwasm-optise sürüm 130'du - wasi-sdk ve binaryen, WebAssembly Exceptions extension'a dayanıyor
- Can I use verisine göre tarayıcı kullanıcılarının %93,86'sı bunu destekleyen bir tarayıcı motoru kullanıyor
- C++, istisnaların yoğun kullanıldığı bir dil olduğu için WebAssembly'nin yerel istisna işleme desteği boilerplate'i azaltabiliyor
- wasmtime ve wazero'da istisna desteğinin açıkça etkinleştirilmesi gerekiyor
- wasmtime için
-W exceptions=yverilebiliyor - wazero için özel bir runner harness gerekiyor
- wasmtime için
- arm makinedeki eski
wasm-opt, istisna işleme komutlarıyla karşılaşınca kapanıyor ve derleme başarısız oluyordu - Bağlama aşamasına
--no-wasm-optverilerek bu yeniden üretilemeyen yol ortadan kaldırıldı
Adres yerleşiminin istisna işleme kodu üretimine etkisi
- Kullanılan Clang sürümü,
wasm2jsderleme sürecindeki istisna işleme yolunda adreslere duyarlı kod üretimi sergiledi - Ham işaretçi değerleri, bazı
try_tablebloklarının çıktı sırasını etkiliyordu- Her derlemede yaklaşık 29 baytlık fark oluşuyordu
- Hesaplamanın kendisi neredeyse aynı olsa da bayt sırası ve
catchreferansları değişiyordu
- arm64 makinede aynı sabit sürüm
wasm2jsderlense bile işaretçi yineleme sırası iş istasyonundan farklı olduğu için aynı sorun ortaya çıktı - Geçici çözüm iki parçadan oluşuyor
setarch --addr-no-randomizeile ilgili derlemede adres alanı rastgeleleştirmesi kapatılıyor- Güvenilen makinelerde x86_64 ve arm64 için ayrı ayrı known-good SHA-256 checksum'ları üretiliyor
- CI,
./utils/wasm/wasm2jsiçinde./build.shçalıştırdıktan sonra checksum'ı doğruluyorshasums.x86_64ile eşleşirse x86_64 checksum doğrulaması geçmiş sayılıyorshasums.arm64ile eşleşirse arm64 checksum doğrulaması geçmiş sayılıyor- Hiçbiri eşleşmezse
wasm-opt_130.wasmvewasm2js_130.wasmiçin SHA-256 yazdırılıyor ve işlem başarısız oluyor
- Bu CI işi hem x86_64 hem de arm64 host'larda çalışıyor
- Tüm host'lar arasında yeniden üretilebilirlik henüz sağlanmış değil; sorun upstream LLVM hatası olarak duruyor
- Mevcut durumda en azından aynı mimari içinde derlemeler deterministik çalışıyor
1 yorum
Lobste.rs görüşleri
clangın gizlice$PATHiçindekiwasm-optu çalıştırdığını ilk kez öğrendim ve bunun gerçekten saçma olduğunu düşündümBunun
zig ccyi de etkileyip etkilemediğini kontrol ettim; neyse ki yalnızcaclanglinker driver olarak kullanıldığında çalışıyormuş, yani durum bu değilmişclangadres yerleşimine bağlı olarak sıralama belirliyorsa, ben bunu şahsen bir bug sayarım ve en güncel sürümlerde de yeniden üretilebiliyorsa bu şekilde rapor ederdimBu tür sorunları ortadan kaldırma çabası yıllardır sürüyor
clang.exeyi güvenilir biçimde bir cross-compiler olarak kullanmaya çalışırsanız daha da çıldırtıcı oluyorclang, native sistem için derleme yapacağını varsaydığı yaklaşık 500 farklı yola sahipEleştirmek istemiyorum; bunun açık kaynak olduğunu ve OP'nin popüler bir hizmeti ücretsiz sunduğunu takdir ediyorum
Yine de webin bu hale gelmesinden gerçekten nefret ediyorum. Artık bir web sitesine her girdiğimde Anubis yükleme sayfasının pat diye çıkması sıradanlaştı; popüler her sitede proof-of-work splash screen gösteren bir web isteyip istemediğimizden emin değilim
AI crawler'lar durmadan akın ederken alternatifin ne olduğunu da bilmiyorum ama proof-of-work'ün gerçekten AI crawler'ları engellediğine dair kanıt olup olmadığını da merak ediyorum. Bunların devasa fonları var ve zaten bir sayfayı okumak için çok daha fazla hesaplama yapıyorlar; bu yüzden proof-of-work çözme maliyeti çok küçük görünüyor
Anubis pilotunda bu, istenmeyen trafik için açıkça etkili bir caydırıcı olmuş ve neredeyse varsayılan sayılabilecek kurallarla üç uygulamaya gelen isteklerin yaklaşık %90'ını sürekli engellemiş. DDR %71.0, ArcLight %94.6, Catalog %92.4 olmuş
30 Mayıs'ta bot trafiği patladı ve 3 Haziran'da Anubis uygulanana kadar Catalog fiilen hizmet veremez hale geldi; 1 Haziran'daki zirvede 2,1 milyon benzersiz IP'den 3,4 milyon HTTP isteği geldi ve sayfa yükleme süresi 70 saniyenin üstüne çıktı. 4 Haziran'da Anubis uygulandıktan sonra hizmet yeniden kullanıcılar için erişilebilir oldu; uygulamanın işlediği toplam istek sayısı 125 bin, sayfa yükleme süresi ise 2,12 saniye oldu
https://lobste.rs/s/ncyfcp/anubis_pilot_project_report_june_2025
Başka bir vakada da Anubis dağıtılır dağıtılmaz sorun çözülmüş, izleme ekranında tam zaman görülebilmiş ve sonrasında tek bir uyarı bile gelmemiş. Saldırı sürüyormuş ama sunucu yükü en düşük düzeyde kalmış; Anubis'in yalnızca AI scraper engellemesi değil, aynı zamanda DDoS koruması olarak da çalıştığı düşünülüyor
https://lobste.rs/s/67ijih/day_anubis_saved_our_websites_from_ddos
https://orib.dev/tmp/bandwidth.png
Bazı insanlar sadece
meta refreshetiketiyle ya da tıklanması gereken bir butonla bile onları engelliyor. Yani Anubis işe yarıyor ama mesele proof-of-work'ün kendisi değil, beklenmedik davranış olmasıJavaScript'i kapalı bir tarayıcıyla web kullandığım dönemlerden bile daha can sıkıcı hale geliyor. Webin sadece belge odaklı kalmasını isterdim ama artık her yerde Cloudflare, Anubis ve captcha geçitlerinden geçmek gerekiyor
Botların her zaman WAF'ı aşmanın bir yolunu bulacağı, gerçek kullanıcılarınsa yükleme ekranında CPU döngülerini boşa harcayacağı söyleniyordu
Üzücü ama şaşırtıcı değil. Compiler toolchain'leri, “yerel bağlam zaten doğru olmak zorunda” türünden saçma örtük bağımlılıklara uzun bir geçmiş boyunca yaslandı
Yine de LLVM bu tür bağımlılıkları ortadan kaldırmada öncü olmuştu; bu yüzden clang'da bunu görmek garip geliyor. Örneğin bunun sayesinde Rust compiler, ayrı bir cross-compiler kavramı olmadan da mümkün hale geldi
Bunu, mevcut build araçlarına yaslanmadan bir işletim sistemini bootstrap etmeye çalıştığınız anda hemen görüyorsunuz. Bir kernel oluşturmak, o kernel için libc ve compiler üretip çalıştırmak, ardından yeni OS üzerinde her şeyi baştan derlemek; bunların hepsi örtük varsayımlarla dolu, gülünç derecede karmaşık ve hassas bir süreç
Bu nadir bir sorun alanı olduğu için çoğunlukla yalnızca OS ve compiler geliştiricilerine dokunuyor; bu yüzden de iyi araçlar ya da best practice'ler neredeyse yok ve her compiler+OS kombinasyonunda tüm sistemi gerçekten anlayan kişi sayısı dünya genelinde belki 5'tir
Zig toolchain'inin de bu yeteneklerin bir kısmını LLVM'den aldığını sanıyordum; tabii daha temiz bir ayrım için çok iş yapmış olmalarını anlıyorum. Şimdi artık LLVM kullanmıyorlar mı diye de merak ediyorum
Ama clang'da da aynı sorun varsa, LLVM'den daha temiz bir mimari miras alınmamış mı diye düşündürüyor
Nix kullandığını sanıyordum; ortam değişkenliğinin en azından bir kısmını azaltmak için neden Nixten söz etmediğini ya da onu kullanmadığını merak ediyorum
Mesela
$PATHiçindekiwasm-optsorunu gibi bir şey Nix ile hafifletilebilirmiş gibi geliyor; kullandı da ben mi kaçırdım?Safça, wasm'i asm.js'ye taşımanın “kolay” olacağını düşünmüştüm; bugün yeni bir şey öğrenmiş oldum
Blog başlığı clickbait gibi ama içerik iyi
Clickbait'ten gerçekten nefret ediyorum