QueryProxy
Doküman menüsü

Yapılandırma

Tüm QueryProxy ortam değişkenleri — limitler, zaman aşımları, TLS, sırlar, SCIM, Slack, şema gezgini, metrikler, SIEM, vekiller, uygulama veritabanı, kuyruk.

Güncelleme:

Tüm yapılandırma ortam değişkenleriyle yapılır (yerelde .env, Docker’da konteyner ortamı). Depodaki .env.example tam seti belgeler; bu sayfa gerçekten değiştireceğiniz olanları açıklar.

QueryProxy ayarları

Değişken Varsayılan Anlamı
QUERYPROXY_SELECT_DEFAULT_LIMIT 1000 LIMIT’siz SELECT’lere eklenen limit
QUERYPROXY_SELECT_HARD_LIMIT 10000 Daha büyük LIMIT’ler bu değere indirilir
QUERYPROXY_EXECUTION_TIMEOUT 300 Tek bir talebin işçide çalışabileceği en uzun süre (sn). Sıfırdan büyük tam sayı saniye olmalı; başka her değer (metin, boş, 0, negatif, ondalık, birimli değer) 300’e düşer. Üst sınır 86400 saniyedir (24 saat): bunu aşan geçerli bir değer hata vermez, 86400’e kırpılır. Docker entrypoint’i değeri kırptığında [entrypoint] uyarısı basar. Veritabanı tarafındaki ifade zaman aşımı bundan türetilir (çalıştırma zaman aşımı eksi 5 saniye, en az 1); böylece veritabanı job’dan önce durur. Bkz. Okuma kimlik bilgileri ve zaman aşımları
QUERYPROXY_LOCK_TIMEOUT 5 Hedef veritabanında bir ifadenin kilit için, veritabanı vazgeçmeden önce bekleyeceği saniye. Yalnızca rakam, 1 ile 3600 arası. Daha büyük değer 3600’e kırpılır; başka her değer (metin, boş, 0) 5’e düşer
QUERYPROXY_CONNECTION_SLOTS 2 Bir hedef bağlantıda aynı anda kaç talebin çalışabileceği. Kalanlar queued durumunda bekler ve bir yuva boşalınca başlar; 0 sınırı kapatır
QUERYPROXY_CONNECTION_SLOT_RETRY_DELAY 5 Tüm yuvaları dolu bulan bir talebin yeniden denemeden önce bekleyeceği saniye
QUERYPROXY_SCHEMA_TIMEOUT 5 Şema gezgininin katalog okumasının ifade zaman aşımı, saniye. Bkz. Şema gezgini
QUERYPROXY_SCHEMA_CACHE_TTL 3600 Bir bağlantının şemasının önbellekte kalma süresi, saniye; 0 önbelleği kapatır
QUERYPROXY_SCHEMA_REFRESH_LIMIT 3 Bir kullanıcının bağlantı ve dakika başına isteyebileceği elle şema yenilemesi
QUERYPROXY_SCHEMA_MAX_COLUMNS 20000 Tek bir şema okumasının döndürdüğü en çok sütun; daha büyük şema bir tablo sınırında kesilir
QUERYPROXY_RESULT_DISK local Sonuç dosyaları için Laravel disk adı (s3 desteklenir; herkese açık görünürlükteki diskler reddedilir)
QUERYPROXY_RESULT_TTL_DAYS 30 results:prune sonuçları kaç gün sonra siler
QUERYPROXY_SEED_DEMO false Yalnızca Docker: ilk açılışta demo takımı oluştur (tek rastgele parola, loglara bir kez yazılır; QUERYPROXY_SEED_DEMO_FORCE=true olmadıkça APP_ENV=production iken reddedilir)
QUERYPROXY_ADMIN_EMAIL / QUERYPROXY_ADMIN_PASSWORD — Yalnızca Docker: kurulumda hiç kullanıcı yokken açılışta ilk sistem yöneticisini oluştur (parola en az 8 karakter); herhangi bir kullanıcı olduğu anda etkisizdir
QUERYPROXY_ADMIN_NAME Admin Yalnızca Docker: o ilk yöneticinin görünen adı
QUERYPROXY_RUN_WORKER true Yalnızca Docker: kuyruk işçisini konteyner içinde çalıştır; işçi kendi konteynerinde koşuyorsa false yapın. Helm chart’ı bunu Deployment başına ayarlar (bkz. Kubernetes)
QUERYPROXY_RUN_SCHEDULER true Yalnızca Docker: zamanlayıcıyı (schedule:work) konteyner içinde çalıştır; kurulum başına tam olarak bir zamanlayıcı bulunsun
QUERYPROXY_WORKER_PROCESSES 1 Yalnızca Docker: kuyruk işçisi süreç sayısı
QUERYPROXY_WORKER_TIMEOUT çalıştırma zaman aşımı + 10 İşçinin --timeout değeri; Docker entrypoint’i bunu QUERYPROXY_EXECUTION_TIMEOUT’tan türetir (ayrı bir işçi konteynerinde de aynıdır). Geçersiz kılınamaz: entrypoint her açılışta yeniden hesaplar ve verdiğiniz değeri yok sayar. Bunun yerine çalıştırma zaman aşımını değiştirin. Docker dışında queue:work için --timeout’u kendiniz ayarlayın
QUERYPROXY_KEY_FILE /var/www/html/storage/app/.app_key Yalnızca Docker: APP_KEY verilmediğinde üretilen anahtarın saklandığı dosya. Değişken ayarlı değilse ve eski yolda (/var/www/html/database/.app_key) bir anahtar dosyası zaten varsa, entrypoint o dosyayı kullanmaya devam eder
QUERYPROXY_REQUIRE_2FA none TOTP iki adımlı doğrulamayı zorunlu kıl: none, admins, dba (yöneticiler + DBA rolü olan herkes) veya all
QUERYPROXY_LOCAL_LOGIN all Parola girişinin kapsamı: all, admins_only (parolayı yalnızca sistem yöneticileri kullanır, break-glass erişimi için) ya da none (parola girişi ve parola sıfırlama kapalı; önce SSO çalışmalı). Bilinmeyen değer admins_only sayılır. Bkz. Tek oturum açma
QUERYPROXY_OIDC_ISSUER / QUERYPROXY_OIDC_CLIENT_ID — İkisi de ayarlanınca OpenID Connect ile tek oturum açma açılır. Bkz. Tek oturum açma
QUERYPROXY_OIDC_CLIENT_SECRET — İstemci secret’ı; QUERYPROXY_OIDC_CLIENT_SECRET_FILE onu dosyadan okur
QUERYPROXY_OIDC_SCOPES openid email profile Sağlayıcıdan istenen kapsamlar, boşlukla ayrılmış; bazı sağlayıcılar groups eklenmesini ister
QUERYPROXY_OIDC_GROUP_CLAIM groups Kullanıcının gruplarını listeleyen claim; realm_access.roles gibi noktalı yol izlenir
QUERYPROXY_OIDC_ROLE_MAP — Virgülle ayrılmış grup:takım:rol girdileri; takım slug ya da addır, rol dba, developer ya da auditor’dır. Her SSO girişinde uygulanır
QUERYPROXY_SCIM_ENABLED false /scim/v2 altında SCIM 2.0 kullanıcı sağlamayı sunar; kapalıyken her SCIM yolu 404 döner. Bkz. SCIM ile kullanıcı sağlama
QUERYPROXY_SCIM_RATE_LIMIT 300 Her SCIM token’ı için dakikadaki istek; başarısız doğrulamalar adres başına aynı sayıyla sınırlanır
QUERYPROXY_API_TOKEN_MAX_DAYS 90 API kişisel erişim token’ının en uzun ömrü, gün olarak. Bkz. REST API ve token’lar
QUERYPROXY_API_RATE_LIMIT 60 Her token için dakikadaki API çağrısı; başarısız kimlik doğrulamalar da adres başına aynı sayıyla sınırlanır
QUERYPROXY_CHAT_WEBHOOK_ALLOWED_HOSTS — Giden chat webhook’ları için ek izinli hostlar, virgülle ayrılmış ve * jokerli (SSRF koruması; hooks.slack.com, *.webhook.office.com, *.logic.azure.com ve *.powerplatform.com varsayılan olarak izinlidir)
QUERYPROXY_CHAT_INCLUDE_SQL literals_redacted Chat bildirimlerindeki SQL önizlemesi: literals_redacted (metin ve sayı literalleri ? ile değiştirilir), full (gönderildiği gibi) veya none. Eski boolean değerler de çalışır: true full, false none demektir
QUERYPROXY_SLACK_CLIENT_ID / QUERYPROXY_SLACK_CLIENT_SECRET — OAuth kurulumu için Slack uygulamasının istemci kimlik bilgileri. Bkz. Slack entegrasyonu
QUERYPROXY_SLACK_SIGNING_SECRET — Slack uygulamasının signing secret’ı; Slack’in gönderdiği her isteği doğrular
QUERYPROXY_SLACK_RATE_LIMIT 300 Slack çalışma alanı başına dakikadaki istek; imza doğrulandıktan sonra sayılır (öncesinde bir adres dakikada 120 ile sınırlıdır)
QUERYPROXY_SECRET_CACHE_TTL 300 Çözülmüş harici sırrın süreç belleğinde kalma süresi, saniye; 0 önbelleği kapatır. Bkz. Harici gizli bilgi referansları
QUERYPROXY_SECRET_TIMEOUT 5 Bir sır deposunun bağlanması ve yanıtlaması için tanınan saniye
QUERYPROXY_VAULT_*, QUERYPROXY_AWS_REGION, QUERYPROXY_AZURE_* — HashiCorp Vault, AWS Secrets Manager ve Azure Key Vault bağlantısı; tüm değişkenler Harici gizli bilgi referansları sayfasında
QUERYPROXY_PENDING_REMIND_AFTER 4 Bir talebin pending kalabileceği saat sayısı; sonrasında takımın DBA’lerine ve yöneticilerine portalda ve chat’te bir hatırlatma gider. 0 hatırlatmayı kapatır; talepler her iki durumda da zaman aşımına uğramaz
QUERYPROXY_METRICS_TOKEN — GET /metrics için bearer token; 24 ya da daha fazla rastgele karakter. Bu ya da izin listesi ayarlanana kadar /metrics 404 döner. Bkz. İzleme
QUERYPROXY_METRICS_ALLOWED_IPS — /metrics’i token olmadan okuyabilecek adreslerin ya da CIDR aralıklarının virgülle ayrılmış listesi (TRUSTED_PROXIES kurallarını izler)
QUERYPROXY_SIEM_SINKS — Açılacak denetim aktarım hedefleri: stdout, syslog, webhook. QUERYPROXY_SIEM_* ayarları Denetim zinciri ve SIEM aktarımı sayfasında listelenir
QUERYPROXY_CONNECTION_HOST_DENYLIST — Bağlantı hedefi olarak engellenen ek hostlar (virgülle ayrılmış)
QUERYPROXY_SQLITE_ALLOWED_DIR — SQLite bağlantı dosyalarını bu dizinle sınırla. Uygulama dizini içindeki dosyalar (QueryProxy’nin varsayılan SQLite veritabanı orada durur) bu ayar verilsin ya da verilmesin her zaman reddedilir
QUERYPROXY_EXTRA_UNTRUSTED_LANGUAGES — Guard’ın CREATE EXTENSION’da reddettiği ek prosedürel diller (virgülle ayrılmış); yerleşik listeyi genişletir. DO, CREATE FUNCTION ve CREATE PROCEDURE bu ayardan bağımsız olarak yalnızca plpgsql ve sql kabul eder
QUERYPROXY_EXTRA_DANGEROUS_VARIABLES — Guard’ın SET ile (MySQL / MariaDB’de kalıcı scope’lar, PostgreSQL’de her scope) ve set_config ile yazılmasını reddettiği ek sunucu değişkenleri (virgülle ayrılmış); yerleşik listeyi genişletir
QUERYPROXY_EXTRA_BLOCKED_FUNCTIONS — Guard’ın doğrudan reddettiği ek fonksiyonlar (virgülle ayrılmış); yerleşik listeyi genişletir
QUERYPROXY_EXTRA_STATE_CHANGING_FUNCTIONS — Bir ifadeyi yazma yapan ek fonksiyonlar (virgülle ayrılmış); yerleşik listeyi genişletir
QUERYPROXY_EXTRA_RESOURCE_CONSUMING_FUNCTIONS — Kaynak tuttukları için (uyku/sleep gibi) bir ifadeyi yazma yapan ek fonksiyonlar (virgülle ayrılmış); yerleşik listeyi genişletir
QUERYPROXY_EXTRA_BLOCKED_PROCEDURES — Guard’ın reddettiği ek SQL Server prosedürleri (virgülle ayrılmış); yerleşik listeyi genişletir
QUERYPROXY_EXTRA_SQLITE_PRAGMAS — Çıplak, okuma biçiminde izin verilen ek SQLite pragma’ları (virgülle ayrılmış); yerleşik listeyi genişletir
TRUSTED_PROXIES — X-Forwarded-* başlıklarını ayarlamasına izin verilen ters vekillerin IP’leri / CIDR’ları (virgülle ayrılmış); boşsa hiçbir vekile güvenilmez
TRUSTED_HOSTS — APP_URL’deki host’a ek olarak bu kurulumun yanıt verdiği hostname’ler (virgülle ayrılmış)
DB_QUEUE_RETRY_AFTER QUERYPROXY_EXECUTION_TIMEOUT + 30 (330) Rezerve edilmiş bir kuyruk job’unun kaç saniye sonra yeniden deneneceği. Ayarlanmamışsa çalıştırma zaman aşımından türetilir; açıkça verilen değer önceliklidir. BEANSTALKD_QUEUE_RETRY_AFTER ve REDIS_QUEUE_RETRY_AFTER aynı şekilde çalışır

retry_after türetilir: DB_QUEUE_RETRY_AFTER’ı (ya da Beanstalkd / Redis karşılığını) kendiniz ayarlamadıkça QUERYPROXY_EXECUTION_TIMEOUT + 30 saniyedir (varsayılan 300 için 330). Docker entrypoint’i, işçinin --timeout (çalıştırma zaman aşımı + 10) ve stopwaitsecs (çalıştırma zaman aşımı + 20) değerlerini de aynı ayardan türetir. retry_after’ı açıkça ayarlarsanız çalıştırma zaman aşımının üzerinde tutun, çünkü sorgu job’u o noktada durdurulur; varsayılan +30 bir pay bırakır. Ona eşit ya da altındaki bir değer, yavaş bir sorgunun hâlâ çalışırken yeniden rezerve edilmesine ve sonra başarısız işaretlenmesine yol açar — yazması commit olabilse bile — ve queue:work (daemon ya da --once) veya queue:listen başlarken bir uyarı loglar. 0.2.0 .env.example’ından kalma sabit bir *_QUEUE_RETRY_AFTER=330 türetmeyi durdurur; bilerek ayarlamadıysanız kaldırın.

Kabul edilen bir QUERYPROXY_REQUIRE_2FA TOTP kodu yakılır, dolayısıyla penceresinin kalanında yeniden kullanılamaz. Pratik bir sonucu: aynı 30 saniyelik adımda ikinci bir cihazdan giriş yapmak için bir sonraki kodu beklemek gerekir.

QUERYPROXY_EXTRA_UNTRUSTED_LANGUAGES ve QUERYPROXY_EXTRA_DANGEROUS_VARIABLES, SQL korumalarının CREATE EXTENSION ve SET’i değerlendirdiği iki listeye ekleme yapar. Yalnızca genişletebilirler: yerleşik girdiler tabandır, ortamın verdiği her şeyin üstüne yeniden eklenir; dolayısıyla kısaltılmış bir liste guard’ı etkisiz kılamaz.

MySQL / MariaDB hedefleri: sql_mode

Guard tırnakları ve ters eğik çizgileri varsayılan biçimde okur; bu yüzden oturum sql_mode’u bunları farklı okuyacaksa talep reddedilir. QueryProxy, bir mysql ya da mariadb bağlantısında SQL’i çalıştırmadan önce @@SESSION.sql_mode değerini okur; NO_BACKSLASH_ESCAPES ya da ANSI_QUOTES içeriyorsa talep başarısız olur ve hiçbir şey çalışmaz; mesaj ilgili bayrağı adıyla belirtir. QueryProxy’nin kendisi bağlanırken, sunucunun varsayılanının yerine geçen katı bir sql_mode ayarlar; bu yüzden denetim tetiklenirse bağlandıktan sonra modu neyin değiştirdiğine bakın (aradaki bir vekil, değişmiş bir bağlantı ayarı). Bayrakları sunucu ve bağlantı kullanıcısı varsayılanlarından uzak tutmak yine de yerindedir, ama tek başına sorunu gidermez. sql_mode’u değiştiren bir SET göndermek her driver’da reddedilir (bkz. SQL korumaları).

Okuma kimlik bilgileri ve zaman aşımları

Bir okuma talebi, hedef veritabanında salt okunur bir oturumda; QueryProxy’nin belirlediği bir ifade zaman aşımı ve kilit zaman aşımıyla çalışır. Driver başına bunun anlamı:

Driver Salt okunur oturum İfade zaman aşımı Kilit zaman aşımı
PostgreSQL SET TRANSACTION READ ONLY statement_timeout (ve idle_in_transaction_session_timeout) lock_timeout
MySQL SET SESSION TRANSACTION READ ONLY MAX_EXECUTION_TIME, yalnızca SELECT innodb_lock_wait_timeout
MariaDB SET SESSION TRANSACTION READ ONLY max_statement_time innodb_lock_wait_timeout
SQL Server yok (motorda salt okunur oturum bulunmaz) PDO sorgu zaman aşımı SET LOCK_TIMEOUT
SQLite PRAGMA query_only yok busy timeout

İfade zaman aşımı QUERYPROXY_EXECUTION_TIMEOUT eksi 5 saniyedir (en az 1); kilit zaman aşımı ise QUERYPROXY_LOCK_TIMEOUT’tur. Yazmalar da aynı sınırları alır. MySQL’de ifade zaman aşımı yazmalara uygulanmaz; bu yüzden orada uzun bir yazma veritabanı tarafından kesilmez, job çalıştırma zaman aşımında biter ve yazma sunucuda yine de sürebilir. Stop query onu daha erken iptal eder.

MySQL ve MariaDB salt okunur modu tüm oturum için ayarlar; bu yüzden örtük commit yapan bir ifade bu moddan sıyrılamaz. PostgreSQL’de bir okuma talebi içinde SELECT … FOR UPDATE ve FOR SHARE reddedilir.

Bir bağlantı isteğe bağlı bir okuma kullanıcı adı ve parolası taşıyabilir (ana kimlik bilgileri gibi şifrelenir). Okumalar bunları kullanır; yazmalar asla kullanmaz. Bağlantı testi ikisini de dener ve okuma kimlik bilgilerinin hatası “Read credentials:” ile başlar. Okuma kullanıcısına yalnızca SELECT yetkisi verin. SQL Server’da okumalar için veritabanı tarafındaki tek koruma budur; çünkü motorda salt okunur oturum yoktur ve ApplicationIntent=ReadOnly yazmalara karşı koruma sağlamaz. SQLite bağlantıları bir okuma kimliği saklamaz.

Hedef veritabanlarına TLS

Her ağ bağlantısının bağlantı formunda bir TLS ayarı vardır. Yeni bağlantılar varsayılan olarak TLS’yi zorunlu tutar: düz metne düşmek yerine başarısız olurlar.

Driver Seçenekler Yeni bağlantı
PostgreSQL require, verify-ca, verify-full, prefer, disable require (şifreli, sunucu doğrulanmaz). verify-ca ve verify-full yapıştırdığınız CA’yı kullanır
MySQL, MariaDB required ya da driver varsayılanına bırakmak; “Verify the server certificate” required, sunucu sertifikası doğrulanmaz
SQL Server required ya da driver varsayılanına bırakmak; “Trust the server certificate” Encrypt=true, TrustServerCertificate=false
SQLite yok yok

PostgreSQL, MySQL ve MariaDB için bir CA sertifikasını, bir istemci sertifikasını ve bir istemci anahtarını PEM olarak yapıştırabilirsiniz. Bunlar şifreli saklanır, çalışma anında storage/app/tls/<connection id>/ altına yazılır (dizin modu 0700, dosyalar 0600) ve bağlantıyla birlikte silinir. Form bunları tarayıcıya asla geri göndermez ve istemci anahtarı parola korumalı olmamalıdır. SQL Server formunda PEM alanı yoktur.

Doğrulamasız require ve required trafiği şifreler ama karşı tarafın kim olduğunu kanıtlamaz; dolayısıyla ortadaki adama (man in the middle) karşı koruma sağlamaz. Ağ tümüyle size ait değilse doğrulamayı açın.

v0.3.0’dan önce var olan bağlantılar eski davranışını korur ve listede “TLS not enforced” (PostgreSQL, sslmode=prefer) ya da “TLS: driver default” olarak işaretlenir; queryproxy:doctor bunları adıyla bildirir. SQL Server’da zorunlu TLS için pdo_sqlsrv eklentisi gerekir: o olmadan Laravel, şifreleme ayarını yok sayan bir bağlantıya sessizce düşerdi; bu yüzden QueryProxy bağlanmayı reddeder. Encrypt=true ile şifreleme sunmayan bir sunucuyu reddetmek ODBC sürücüsünün belgelenmiş davranışıdır; QueryProxy’nin testleri böyle bir sunucuyu simüle edemez.

Dosyadan sırlar

Docker ve Kubernetes sırları dosya olarak gelir. Aşağıdaki her değişken için aynı adı _FILE sonekiyle ayarlayın; entrypoint (ve uygulama) değeri o dosyadan okur:

Değişken Dosya değişkeni
APP_KEY APP_KEY_FILE
APP_PREVIOUS_KEYS APP_PREVIOUS_KEYS_FILE
DB_PASSWORD DB_PASSWORD_FILE
MAIL_PASSWORD MAIL_PASSWORD_FILE
REDIS_PASSWORD REDIS_PASSWORD_FILE
SLACK_BOT_USER_OAUTH_TOKEN SLACK_BOT_USER_OAUTH_TOKEN_FILE
QUERYPROXY_ADMIN_PASSWORD QUERYPROXY_ADMIN_PASSWORD_FILE
QUERYPROXY_METRICS_TOKEN QUERYPROXY_METRICS_TOKEN_FILE
QUERYPROXY_SIEM_WEBHOOK_SECRET QUERYPROXY_SIEM_WEBHOOK_SECRET_FILE
QUERYPROXY_OIDC_CLIENT_SECRET QUERYPROXY_OIDC_CLIENT_SECRET_FILE
QUERYPROXY_VAULT_TOKEN QUERYPROXY_VAULT_TOKEN_FILE
QUERYPROXY_VAULT_SECRET_ID QUERYPROXY_VAULT_SECRET_ID_FILE
QUERYPROXY_AZURE_CLIENT_SECRET QUERYPROXY_AZURE_CLIENT_SECRET_FILE
services:
  app:
    environment:
      APP_KEY_FILE: /run/secrets/queryproxy_app_key
      DB_PASSWORD_FILE: /run/secrets/queryproxy_db_password
      QUERYPROXY_METRICS_TOKEN_FILE: /run/secrets/queryproxy_metrics_token
    secrets: [queryproxy_app_key, queryproxy_db_password, queryproxy_metrics_token]

Kubernetes’te _FILE değişkenini bir Secret volume’ünün bağlandığı yola yönlendirin.

  • Hem X hem X_FILE ayarlamak bir hatadır ve konteyner başlamaz. null, (null) ya da (empty) olarak ayarlanmış düz bir değişken ayarsız sayılır.
  • Dosya var olmalı, okunabilir olmalı ve boş olmamalıdır. Sondaki satır sonları kaldırılır; geri kalan her şey korunur.
  • Hata mesajları değişkeni ve yolu adıyla belirtir, değeri asla yazmaz.
  • php artisan config:cache (imaj her açılışta çalıştırır) çözümlenmiş değerleri, sırlar dahil, bootstrap/cache/config.php içine düz metin olarak yazar. Dolayısıyla dosyadan gelen bir sır da bu cache dosyasında bulunur.
  • Slack ve Teams’in gelen webhook kipindeki imza sırları ile webhook URL’leri ortam değişkeni değildir; uygulama veritabanında şifreli saklanır. Slack uygulamasının kendi kimlik bilgileri (QUERYPROXY_SLACK_CLIENT_SECRET, QUERYPROXY_SLACK_SIGNING_SECRET) düz ortam değişkenleridir ve _FILE biçimi yoktur.

php artisan queryproxy:doctor hangi sırların dosyadan okunduğunu bildirir (secret_files) ve biri okunamıyorsa başarısız olur. Bkz. Sorun giderme.

Tek oturum açma

OpenID Connect ile tek oturum açma, yukarıdaki tablodaki QUERYPROXY_OIDC_* değişkenleriyle yapılandırılır. Sağlayıcıda redirect URI olarak {APP_URL}/auth/oidc/callback kaydedin. Sağlayıcı örnekleri, rol eşlemesi ve hesap oluşturma ile bağlama kuralları Tek oturum açma sayfasındadır. İstemci secret’ı, Dosyadan sırlar bölümündeki diğer sırlar gibi dosyadan gelebilir (QUERYPROXY_OIDC_CLIENT_SECRET_FILE).

Şema gezgini

Query Studio’nun şema paneli ve ad tamamlaması, hedef veritabanının kataloğunu sabit sorgularla, salt okunur bir oturumda ve onaysız okur. Yalnızca bağlantıyı kullanabilen kullanıcılar okuyabilir; yanıt tabloları, görünümleri ve sütunları listeler, veriyi asla.

  • QUERYPROXY_SCHEMA_TIMEOUT bu okumanın ifade zaman aşımıdır, saniye cinsinden. Taleplerin yürütme zaman aşımından ayrıdır. Okuma ayrıca boş bir bağlantı yuvası ister (QUERYPROXY_CONNECTION_SLOTS); bütün yuvalar doluyken panel kullanıcıdan kısa süre sonra yeniden denemesini ister.
  • Sonuç bağlantı başına QUERYPROXY_SCHEMA_CACHE_TTL saniye önbellekte tutulur; bağlantıyı düzenlemek yeni bir kayıt başlatır. Elle Refresh önbelleği atlar ve kullanıcı ile bağlantı başına dakikada QUERYPROXY_SCHEMA_REFRESH_LIMIT ile sınırlıdır. Önbellekte yalnızca adlar ve tipler durur; maskeli sütunlardaki kilit her yanıtta güncel maskeleme kurallarından hesaplanır.
  • QUERYPROXY_SCHEMA_MAX_COLUMNS tek bir okumayı sınırlar. Daha büyük şema, varsayılan şema önce listelenerek bir tablo sınırında kesilir ve panel kesildiğini söyler.
  • MySQL ve MariaDB’de yalnızca bağlantının kendi veritabanı listelenir. Sistem şemaları (information_schema, mysql, performance_schema, sys) asla listelenmez.
  • Veritabanından yapılan her okuma, nesne ve sütun sayılarıyla denetim günlüğüne schema.read olarak yazılır. Önbellekten sunulan okuma yazılmaz.

Uygulama anahtarı ve HTTPS

APP_KEY, saklanan bağlantı kimlik bilgilerinizi ve chat sırlarınızı şifreler. Üretimde açıkça belirleyin ve sabit tutun — yeniden üretilen bir anahtar (ör. konteyner yeniden oluşturulunca) saklanan tüm kimlik bilgilerini okunamaz hale getirir. php artisan key:generate --show ile üretin ve döndürürken eski anahtarı APP_PREVIOUS_KEYS’e (virgülle ayrılmış) taşıyın ki mevcut şifreli veri hâlâ çözülebilsin.

HTTPS’i bir ters vekil arkasından sunarken SESSION_SECURE_COOKIE=true ayarlayın.

Ters vekil arkasında

Kırıcı değişiklik — QueryProxy’nin önünde bir vekil varsa TRUSTED_PROXIES’i ayarlayın. Önceki sürümler her vekile güveniyordu. Bu sürümden itibaren hiçbir vekile varsayılan olarak güvenilmez ve siz kendinizinkini yazana kadar uygulama bağlanan tarafı istemci olarak okur.

TRUSTED_PROXIES, X-Forwarded-* başlıklarını ayarlamasına izin verilen IP’lerin ya da CIDR’ların virgülle ayrılmış listesini alır:

TRUSTED_PROXIES=10.0.0.0/8

Bu liste vekilinizin adını içermedikçe X-Forwarded-Proto yok sayılır — HTTPS algılanmaz, dolayısıyla HSTS başlığı gönderilmez — ve denetim kayıtlarına istemcinin değil vekilin adresi düşer.

Asla * yazmayın. Her vekile güvenmek, herhangi bir istemcinin kendi X-Forwarded-For başlığını göndermesine izin verir; bu, denetim izindeki istemci IP’sini sahteler ve sınırsız giriş ile 2FA denemesi hakkı verir, çünkü iki throttle da IP başına anahtarlanır.

X-Forwarded-Host, listede ne yazarsa yazsın hiç dikkate alınmaz: sahte bir host başlığı parola sıfırlama e-postasındaki bağlantıyı yeniden yazıyordu. İkinci bir katman olarak istek host’u APP_URL’deki host’a (ve www. kardeşine) sabitlenir; böylece mutlak URL’ler — imzalı route’lar, parola sıfırlama e-postaları — her zaman kendi kurulumunuzu gösterir. APP_URL’yi kullanıcıların gerçekten eriştiği adrese ayarlayın.

Kurulum birden fazla ada yanıt veriyorsa diğerlerini TRUSTED_HOSTS’e yazın:

TRUSTED_HOSTS=queryproxy.internal,db.example.com

X-Forwarded-Host yok sayıldığına göre çok alan adlı bir dağıtımı çalıştırmanın desteklenen yolu budur — listelemediğiniz bir hostname yine de bir parola sıfırlama bağlantısını yeniden yazamaz. Adlar APP_URL’deki host’a (ve www. kardeşine) eklenir, onun yerine geçmez. Hostname olarak okunamayan girdiler sessizce atılır, böylece bir yazım hatası kurulumu çökertemez.

İki değer de uygulama yapılandırması üzerinden okunur, bu yüzden .env’e yazmak yeterlidir. Yapılandırmayı cache’liyorsanız değiştirdikten sonra php artisan config:cache’i yeniden çalıştırın; Docker imajı her açılışta yeniden cache’ler.

Uygulama veritabanı

QueryProxy’nin kendi verisi (kullanıcılar, takımlar, talepler, denetim günlüğü) varsayılan olarak SQLite’ta yaşar — sıfır yapılandırma. MySQL, MariaDB, PostgreSQL ya da SQL Server için standart Laravel değişkenlerini ayarlayın:

DB_CONNECTION=pgsql        # veya mysql, mariadb, sqlsrv
DB_HOST=db
DB_PORT=5432
DB_DATABASE=queryproxy
DB_USERNAME=queryproxy
DB_PASSWORD=degistir-beni

Bu, uygulama veritabanıdır — proxy’lediğiniz veritabanları arayüzde Connections altında, takım bazında ve şifreli kimlik bilgileriyle tanımlanır.

SQLite’tan başka bir veritabanına geçiş. QueryProxy’yi durdurun ve php artisan queryproxy:migrate-appdb --to=<dsn> çalıştırın, örneğin --to=pgsql://user:password@host:5432/queryproxy (paroladaki özel karakterleri URL kodlamasıyla yazın). Komut hedefte migration’ları çalıştırır, her tabloyu yabancı anahtar sırasıyla kopyalar, her tablonun satır sayısını karşılaştırır ve hedefte audit:verify çalıştırır. Denetim trigger’ları yerinde kalır; denetim hash’leri ve zincirin başı değişmeden kopyalanır. Hedef boş olmalıdır (yalnızca migrate edilmiş bir veritabanı olabilir). --dry-run her şeyi denetler, hiçbir şey yazmaz; --force olmadan komut QueryProxy’nin durduğunu onaylamanızı ister. Kopya tek bir transaction’dır; bu yüzden hata, yeniden deneyebileceğiniz migrate edilmiş ve boş bir hedef bırakır. cache tabloları kopyalanmaz, hedef parola hiç yazdırılmaz. Sonra DB_CONNECTION ve diğer DB_* ayarlarını değiştirip QueryProxy’yi yeniden başlatın.

Uygulama veritabanı olarak SQL Server. mssql image varyantını kullanın: varsayılan image’ta pdo_sqlsrv yoktur (bkz. SQL Server hedefleri). Bir kurulumu oraya taşımak için php artisan queryproxy:migrate-appdb --to="sqlsrv://user:password@host:1433/queryproxy?trust_server_certificate=true" kullanın. Sorgu dizesindeki trust_server_certificate ve encrypt gibi seçenekler yalnızca o komutun bağlantısına gider. Uygulamada bunlar için ayrı bir DB_* değişkeni yoktur; bu yüzden taşıdıktan sonra aynı DSN’i, aynı seçeneklerle DB_URL içinde verin. Aksi hâlde kendinden imzalı sertifikalı bir sunucuya migrate-appdb ulaşır ama çalışan uygulama ulaşamaz. DB_URL parolayı da taşır; bu yüzden paroladaki özel karakterleri URL kodlamasıyla yazın ve onu DB_PASSWORD kadar gizli tutun. SQL Server, bir tabloya birden fazla cascade yolu veren yabancı anahtarları reddeder ve şemada bunlardan birkaç tane vardır. Bu yüzden yalnızca SQL Server’da sekiz yabancı anahtar ON DELETE NO ACTION ile oluşturulur: query_requests.team_id, masking_rules.team_id, connection_grant_requests.team_id, connections.created_by, connection_user.granted_by, connection_grant_requests.decided_by ve kullanıcılara giden iki query_requests anahtarı (user_id ve reviewed_by); bu ikisi, talep geçmişi bir kullanıcıyla birlikte asla silinmesin diye her sürücüde RESTRICT’tir (ADR-018). Silme sırasında veritabanının yapacağını QueryProxy yapar: bir takımı silmek önce talepleri, maskeleme kurallarını ve tanımlama taleplerini siler; hiç talebi olmayan bir kullanıcıyı kalıcı silmek, ona başvuran anahtarları NULL yapar.

Fark, bir takımı ya da kullanıcıyı silen ham SQL’de ortaya çıkar. SQL Server’da bu silme, takıma ya da kullanıcıya bu sekiz anahtardan biriyle hâlâ başvuran satır varken reddedilir: takım için talepler, maskeleme kuralları ya da tanımlama talepleri; kullanıcı için oluşturduğu bağlantılar, verdiği tanımlamalar, karara bağladığı tanımlama talepleri ya da açtığı veya incelediği talepler. Diğer sürücülerde cascade yapan ya da NULL yapan altı anahtar için SQL Server’da silme, bunun yerine reddedilir. Kullanıcılara giden iki talep anahtarı her sürücüde reddedilir. PostgreSQL, MySQL, MariaDB ve SQLite’ta hiçbir şey değişmez: yeni migration yok, mevcut kurulumda değişiklik yok, silme sonuçları aynı.

Test edilen sürümler. Hedef veritabanları: PostgreSQL 17, MySQL 8.4, MariaDB 11.4 ve 11.8, SQL Server 2022 ve SQLite. Uygulama veritabanı: SQLite, MySQL 8.4, MariaDB 11.4 ve 11.8, PostgreSQL 17 ve SQL Server 2022 (mssql image varyantı). PostgreSQL uyumlu hedef veritabanları: CockroachDB v25.4 ve YugabyteDB 2025.2; bilinen farkları, SQL korumasının CockroachDB’de neleri kapsamadığı dahil, PostgreSQL uyumlu veritabanları sayfasında listelenir. Diğer sürümler çalışabilir ama test edilmez.

Kuyruk

Kuyruk varsayılan olarak veritabanı tabanlıdır (Redis gerekmez). Redis’e taşımak için:

QUEUE_CONNECTION=redis
REDIS_HOST=redis

REDIS_QUEUE_RETRY_AFTER isteğe bağlıdır: ayarlanmamışsa QUERYPROXY_EXECUTION_TIMEOUT + 30 saniyeden türetilir (bkz. ayar tablosunun altındaki not). Yalnızca bu değeri geçersiz kılmak için ayarlayın ve çalıştırma zaman aşımının üzerinde tutun.

İşçi komutu aynı kalır. --timeout değerini çalıştırma zaman aşımının biraz üzerinde tutun (çalıştırma zaman aşımı + 10 saniye; QUERYPROXY_EXECUTION_TIMEOUT varsayılan olarak 300’dür, dolayısıyla 310):

php artisan queue:work --queue=queries,default --tries=1 --timeout=310

Manuel kurulumda bu sayı sizin için türetilmez: QUERYPROXY_EXECUTION_TIMEOUT’u değiştirirseniz --timeout’u da ona göre değiştirin (Docker entrypoint’i bunu kendisi türetir).

Aynı uyarı (retry_after’ın çalıştırma zaman aşımına eşit ya da altında olması) yalnızca daemon queue:work için değil, queue:listen ya da queue:work --once başlarken de bir kez loglanır. queue:listen’ın başlattığı kısa ömürlü queue:work --once süreçleri bunu tekrarlamaz.

Deponun docker-compose.yml dosyasındaki ayrı worker örneği artık --timeout=310 değerini sabit yazmaz: imaj entrypoint’inin QUERYPROXY_EXECUTION_TIMEOUT + 10 olarak türettiği QUERYPROXY_WORKER_TIMEOUT’u geçirir. O servis için QUERYPROXY_EXECUTION_TIMEOUT’u ayarlayın, işçi onu izler. Bu, imajın varsayılan entrypoint’ini gerektirir; bu yüzden worker servisinde entrypoint:’i geçersiz kılmayın.

S3 üzerinde sonuç depolama

QUERYPROXY_RESULT_DISK=s3 ve standart AWS_* değişkenlerini ayarlayın. Sonuç dosyaları NDJSON olarak, akış hâlinde yazılır — bellek kullanımı sonuç boyutundan bağımsız olarak sabit kalır.

Disk özel olmalıdır. Sonuç yolları tahmin edilebilirdir (results/{team_id}/{id}.ndjson); bu yüzden herkese açık sunulan bir disk, indirme yetkilendirmesini tümden atlayarak her takımın satırlarını doğrudan web kökünden dağıtırdı. Bu nedenle QUERYPROXY_RESULT_DISK public diskini ya da visibility => public ile yapılandırılmış herhangi bir diski gösteriyorsa QueryProxy sonuç yazmayı reddeder ve talep bunun yerine açık bir mesajla başarısız olur.

SQL Server hedefleri

Varsayılan Docker imajı pdo_pgsql, pdo_mysql ve pdo_sqlite ile gelir. Microsoft SQL Server hedefleri için mssql imaj varyantını kullanın: queryproxy/queryproxy:<sürüm>-mssql ya da son kararlı sürüm için queryproxy/queryproxy:mssql. Microsoft’un ODBC Driver 18’ini ve pdo_sqlsrv eklentisini ekler; linux/amd64 ve linux/arm64 için derlenir, varsayılan imaj gibi taranır, imzalanır ve attestation taşır. :mssql yalnızca kararlı sürümlerle ilerler ve latest etiketini asla almaz. Microsoft’un sürücüsü Microsoft’un kendi lisansı altındadır (https://aka.ms/odbc18eula); varyantı kullanmak onu kabul etmek demektir.

Varyantı kendiniz derlemek için deponun Dockerfile’ına --build-arg INSTALL_SQLSRV=1 verin. Onaylı sorgular işçide çalıştığı için eklentilerin hem web sürecini hem kuyruk işçisini çalıştıran PHP derlemesinde bulunması gerekir: bir kurulumun her rolünde aynı varyantı çalıştırın.

Stop query için yetkiler

Stop query, çalışan ifadeyi ikinci bir bağlantıdan iptal eder. PostgreSQL, MySQL ve MariaDB’de bağlantı kullanıcısının sahip olduğunun ötesinde ek yetki gerekmez (başkalarının oturumları için pg_signal_backend ya da CONNECTION_ADMIN yeterlidir). SQL Server’da bağlantının login’i şunlara ihtiyaç duyar:

  • VIEW SERVER STATE: bu olmadan sys.dm_exec_sessions yalnızca çağıranın kendi oturumunu gösterir, çalışma bulunamaz ve talep sunucuya sinyal gönderilmeden cancelled olarak işaretlenir (bir uyarı görünür ve ifade zaman aşımında biter).
  • ALTER ANY CONNECTION: KILL <spid> buna ihtiyaç duyar.

SQL Server’da Stop oturumu sonlandırır; bu yüzden açık bir transaction sunucuda geri alınır. Diğer driver’larda yalnızca ifade iptal edilir. Düğme SQLite için gösterilmez.

Bir ifade başladıktan sonra QueryProxy ağ kopmasında yeniden bağlanmaz; çalışma, yeni bir oturumda devam etmek yerine başarısız olur.

Gezinmek için ok tuşları, açmak için Enter.