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_aftertüretilir:DB_QUEUE_RETRY_AFTER’ı (ya da Beanstalkd / Redis karşılığını) kendiniz ayarlamadıkçaQUERYPROXY_EXECUTION_TIMEOUT+ 30 saniyedir (varsayılan300için330). Docker entrypoint’i, işçinin--timeout(çalıştırma zaman aşımı + 10) vestopwaitsecs(ç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 — vequeue:work(daemon ya da--once) veyaqueue:listenbaşlarken bir uyarı loglar. 0.2.0.env.example’ından kalma sabit bir*_QUEUE_RETRY_AFTER=330tü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
XhemX_FILEayarlamak 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.phpiç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_FILEbiç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_TIMEOUTbu 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_TTLsaniye ö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 dakikadaQUERYPROXY_SCHEMA_REFRESH_LIMITile 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_COLUMNStek 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.readolarak 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 olmadansys.dm_exec_sessionsyalnızca çağıranın kendi oturumunu gösterir, çalışma bulunamaz ve talep sunucuya sinyal gönderilmedencancelledolarak 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.