Jump to content

LuaSandbox

From mediawiki.org
This page is a translated version of the page LuaSandbox and the translation is 100% complete.
deneme tahtalı Lua kodunun kullanımına izin veren MediaWiki uzantısı, Extension:Scribunto sayfasına bakın.

LuaSandbox PHP 7 ve PHP 8 için, güvenilmeyen Lua 5.1 kodunun PHP içinden güvenli bir şekilde çalıştırılmasına izin veren bir uzantıdır; bu, genellikle bir Lua ikili dosyasına göndermekten ve süreçler arası iletişimi kullanmaktan daha hızlı olacaktır.

Kurulum

Ön paketli

LuaSandbox, Debian 10 ve Ubuntu 18.04 ve sonraki sürümlerde mevcuttur. Aşağıdaki komutla yükleyin:

apt install php-luasandbox -y

PECL

LuaSandbox artık önceden oluşturulmuş Windows DDL'leri de sağlayan PECL'de mevcuttur. Paket sayfamıza bakın. Önce, aşağıda "el kurulum" altında açıklandığı gibi doğru Lua 5.1 kitaplığını edinin. Sonra çalıştırın:

pecl install luasandbox

El kurulum

Gereksinimler

PHP ve Lua 5.1 için başlıkları ve kitaplık dosyalarını kurun.

  • Ubuntu gibi Debian'dan türetilen Linux dağıtımları için:
    apt install php-dev liblua5.1-0-dev -y
    
  • CentOS/Redhat'tan türetilen Linux dağıtımları için:
    yum install php-devel lua5.1 lua5.1-devel
    
  • macOS için:
    brew install lua
    

İndir

Kaynak kodunu git'ten uygun bir dizine indirin:

git init
git pull https://gerrit.wikimedia.org/r/mediawiki/php/luasandbox.git

Veya bir anlık görüntü indirin ve paketi açın.

Yapı

luasandbox burada LuaSandbox Git deposunun klonlandığı dizindir.

cd luasandbox
phpize && ./configure && make && sudo make install

Ardından PHP yapılandırmasına uygun bir yere extension=luasandbox.so ekleyin. Örneğin, modern Debian'dan türetilen dağıtımlarda /etc/php/$version/mods-available ile bir dosya eklersiniz (burada $version, LuaSandbox'a uyduğunuz PHP sürümüdür) ve bunu etkinleştirmek için phpenmod komutunu kullanırsınız.

LuaSandbox'ı MediaWiki gibi bir web uygulamasıyla kullanıyorsanız, uzantıyı yüklemek için web sunucunuzu veya PHP için php-fpm yeniden başlatmanız gerekir. Böyle bir yeniden yüklemeden sonra, LuaSandbox'ı phpinfo() ve get_loaded_extensions() (ve Scribunto yüklü MediaWiki için Special:Version) çıkışında görmelisiniz.

Örnekler

$sandbox = new LuaSandbox;
$sandbox->setMemoryLimit( 50 * 1024 * 1024 );
$sandbox->setCPULimit( 10 );

// Lua ortamında bazı işlevleri kaydedin

function frobnosticate( $v ) {
    return [ $v + 42 ];
}

$sandbox->registerLibrary( 'php', [
    'frobnosticate' => 'frobnosticate',
    'output' => function ( $string ) {
        echo "$string\n";
    },
    'error' => function () {
        throw new LuaSandboxRuntimeError( "Bir şey yanlış" );
    }
] );

// PHP'ye ve Lua'ya yapılan geri aramalar dahil olmak üzere bazı Lua kodlarını yürütün

$luaCode = <<<EOF
php.output( "Hello, world" );

return "Hi", function ( v )
    return php.frobnosticate( v + 200 )
end
EOF;

list( $hi, $frob ) = $sandbox->loadString( $luaCode )->call();
assert( $frob->call( 4000 ) === [ 4242 ] );

// PHP tarafından atılan LuaSandboxRuntimeError istisnaları Lua içinde yakalanabilir

list( $ok, $message ) = $sandbox->loadString( 'return pcall( php.error )' )->call();
assert( !$ok );
assert( $message === 'Something is wrong' );

Belgelendirme

Belgelerimiz artık https://www.php.net/book.luasandbox adresindeki yukarı akış PHP kılavuzunda yaşıyor.

Kılavuzu değiştirmek istiyorsanız, GitHub'daki PHP kılavuz deposuna karşı bir çekme talebi gönderebilir veya uzantının Gerrit projesindeki LuaSandbox bölümünün aynasını değiştirebilirsiniz.

Standart Lua'dan farklılıklar

LuaSandbox, standart Lua 5.1'den bazı yönlerden farklı olan deneme tahtalı bir ortam sağlar.

Aşağıdaki işlevler ve paketler kullanılamaz:

  • Doğrudan dosya sistemi erişimine izin verdikleri için dofile(), loadfile() ve io paketi. Gerekirse, dosya sistemine erişim PHP geri çağrıları yoluyla yapılmalıdır.
  • Büyük ölçüde doğrudan dosya sistemi erişimine bağlı olduğundan, require() ve module() dahil olmak üzere package. Bunun yerine Scribunto'da kullanılan gibi bir saf Lua yeniden yazma kullanılabilir.
  • Lua kodunun statik analizine izin vermek için load() ve loadstring().
  • Standart çıkışa çıktığı için print(). Gerekirse, çıkış PHP geri çağrıları yoluyla yapılmalıdır.
  • İşlemin manipüle edilmesine ve diğer işlemlerin yürütülmesine izin verdiği için os paketinin çoğu.
    • os.clock(), os.date(), os.difftime() ve os.time() mevcut kalır.
  • debug paketin çoğu, Lua durumunun ve meta verilerin deneme tahtasına bozabilecek şekillerde manipüle edilmesine izin verdiği için.
    • debug.traceback() kullanılabilir durumda kalır.
  • string.dump(), çünkü dahili verileri açığa çıkarabilir.
  • collectgarbage(), gcinfo() ve coroutine paketi güvenlik açısından incelenmemiştir.

Aşağıdaki özellikler değiştirildi:

  • pcall() ve xpcall() belirli hataları, özellikle zaman aşımı hatalarını yakalayamaz.
  • tostring(), işaretçi adreslerini içermez.
  • Özyineleme derinliğini sınırlamak ve bir zaman aşımını periyodik olarak kontrol etmek için string.match() yamalandı.
  • math.random() ve math.randomseed(), PHP'nin rand() ile durumu paylaşmayan sürümlerle değiştirilir.
  • Lua 5.2 __pairs ve __ipairs meta yöntemleri pairs() ve ipairs() tarafından desteklenir.

Geçmiş

Yıllar geçtikçe, MediaWiki'nin vikimetin şablon dili daha fazla özellik kazandı ve daha karmaşık hâle geldi. 2009 gibi erken bir tarihte, MediaWiki geliştiricileri, vikimetni daha karmaşık hâle getirmeye devam etmek yerine gerçek bir betik dili yerleştirme fikrini tartışmaya başladılar.

Böyle bir proje için gereksinimler, üretim sunucularında güvenilmeyen kullanıcı kodunu çalıştıracağından, güçlü bir deneme tahtası ve bellek ve CPU zaman kullanımında katı sınırlamaları içeriyordu. Daha iyi performans için büyük bir fayda sağlamak için süreç içinde bir PHP uzantısı aracılığıyla çalıştırılabilme özelliği ile bağımsız bir ikili dosyaya bombardıman edilerek kullanılabilir olması gerekir.

Geliştirme 2011'de ciddi bir şekilde başladığında, dört aday dil belirlendi: Lua, JavaScript, PHP veya geliştirilecek varsayımsal bir "WikiScript" dili. Lua'nın birkaç avantajı vardı:

  • Küçük (170K bağımsız) ve hızlı. LuaJIT'in varlığı da bir fayda olarak kabul edildi.
  • CPU ve bellek sınırlaması için kolay kancalar dahil olmak üzere gömmek için tasarlanmıştır.
  • Kolay deneme tahtası, dahili küresel yok.
  • Gömme talimatları da dahil olmak üzere ayrıntılı kaynak kılavuzu.

Ana dezavantajı, JavaScript kadar yaygın olarak bilinmemesiydi.

O zamanlar V8 motoru biçimindeki JavaScript'in birkaç dezavantajı vardı:

  • Gömmeyle ilgili minimum belgelendirme.
  • Belirsiz gömme için devam eden destek.
  • Ayırma kancası yok.
  • Büyük bağımsız ikili dosya.

Rhino motoru daha kötüydü, Java ile yazıldığı için aklı başında PHP'ye yerleştirilemezdi. Doğru gömme ve deneme tahtası oluşturma son derece zor olacağından ve ön ayrıştırma yavaş olacağından PHP'nin kendisi reddedildi ve "WikiScript" sıfırdan bir (veya iki) yorumlayıcı geliştirmeyi gerektireceğinden çok daha büyük bir proje olacaktı.

Bu nedenle, Lua, özellikle o sırada mevcut olan 5.1 sürümü seçildi ve bu PHP uzantısı geliştirildi. 5.2'de ortam işleme işlevinde yapılan değişiklikler, o zamandan beri basit bir yükseltmeyi engelledi, ayrıntılar için phab:T178146 sayfasına bakın.

Dış bağlantılar