Documentation
¶
Overview ¶
Package proxy wires an inbound (user) channel to an outbound (target) channel and shuttles data and requests between them.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrAccessDenied: kimlik ya da yetki reddi — bir arıza DEĞİL, // güvenlik olayı. Çağıran bunu istemciye "access denied" olarak // yansıtır (SSH reject sebebi / HTTP 403). ErrAccessDenied = errors.New("proxy: access denied") // ErrIdleTimeout / ErrMaxLifetime: oturumu KAPATAN sınırlar. // Hata olarak çağırana dönmezler — context.Cause ile okunup denetim // kaydına yazılırlar (bkz. idle.go). ErrIdleTimeout = errors.New("proxy: session idle timeout") ErrMaxLifetime = errors.New("proxy: session max lifetime") // ErrRecordingFailed: kayıt yazımı oturum ortasında bozuldu. // Oturum KAPATILIR — kayıtsız oturum yok. ErrRecordingFailed = errors.New("proxy: recording failed") // erişilemiyor. Kullanıcının suçu değil; birinin müdahale etmesi // gerekir. Çağıran "connection failed" / HTTP 503 der. ErrUnavailable = errors.New("proxy: session unavailable") )
var ErrDirectoryRefused = errors.New("proxy: the directory no longer vouches for this user")
* ErrDirectoryRefused, kimlik kaynağının bu kullanıcı için oturumu * reddettiği: dizinde YOK ya da hesap KAPATILMIŞ. * * Arızadan ayrı bir hata olması şart. "Cevap veremedim" ile "bu kişi * artık burada değil" aynı yola düşerse, bir dizin kesintisi ya herkesi * dışarıda bırakır ya da kapatılmış hesapları içeri alır — hangi tarafa * eğdiğimize bakmaksızın yanlış.
var ErrShortPayload = errors.New("proxy: request payload too short")
ErrShortPayload, payload beklenen alanları taşımayacak kadar kısaysa döner.
var ErrShuttingDown = errors.New("proxy: the bastion is shutting down")
* ErrShuttingDown: bastion kapanıyor ve bekleme süresi doldu. * * ⚠️ ErrTerminated'DAN AYRI TUTULUYOR. İkisi de oturumu kapatıyor ama * denetim kaydına ve kullanıcıya bambaşka şeyler söylüyorlar: biri "bir * yönetici seni kesti", öbürü "makine yeniden başlıyor". Aynı sebebi * kullansaydık, bir dağıtım gecesi denetim defteri kimsenin yapmadığı * yüzlerce kesme ile dolardı.
var ErrTerminated = errors.New("proxy: session terminated by an administrator")
ErrTerminated: oturumu bir yönetici kesti. bound()'un ürettiği ErrIdleTimeout / ErrMaxLifetime ile aynı raftadır: Run bunu context.Cause'dan okuyup denetim satırına "closed_by" olarak yazıyor.
Functions ¶
func TerminatedBy ¶
* TerminatedBy, kesme sebebinden KİMİN kestiğini çıkarır. * * ⚠️ errors.As, metin bölme DEĞİL. Aktör tipli hatanın alanında * duruyor; sebebi Error() metninden geri kazımak, içinde ": " geçen bir * adı sessizce kırpardı.
Types ¶
type Broker ¶
type Broker struct {
// contains filtered or unexported fields
}
Broker, bir kullanıcı kanalı (down) ile bir hedef kanalı (up) arasında veriyi ve request'leri iki yönde taşır.
func New ¶
func New(down ssh.Channel, downR <-chan *ssh.Request, up ssh.Channel, upR <-chan *ssh.Request, rec *record.Writer, recordInput bool, policy RequestPolicy, logger *slog.Logger) *Broker
New wires an inbound channel to an outbound one.
rec nil geçilebilir (kayıt kapalı). recordInput yalnızca config açıkça istediğinde true olmalı.
type Deps ¶
type Deps struct {
Store *store.Store
Records *record.Store
/*
* RecordMinFree, altına inildiğinde YENİ oturumun reddedildiği boş
* alan. 0 kapalı. Gerekçesi Open'daki kullanım yerinde.
*/
RecordMinFree uint64
Authority *ca.CA
Logger *slog.Logger
RecordInput bool
// Requests, oturum kanalı request'lerinin süzgeci (requests.go).
// Sıfır değeri kullanılabilir: env whitelist'i varsayılana düşer,
// tip listeleri zaten sabit.
Requests RequestPolicy
// IdleTimeout, iki yönde de bayt akmayan oturumun kapatılma süresi.
// 0 = kapalı (bkz. config.SessionConfig.IdleTimeout).
IdleTimeout time.Duration
// MaxLifetime, oturumun mutlak ömrü. 0 = kapalı.
MaxLifetime time.Duration
// Probe, hedefte KOMUT ÇALIŞTIRARAK tanıma. Sıfır değeri KAPALI —
// yani hiçbir şey çağırmadıkça postern hedefte kullanıcının oturumu
// dışında bir şey çalıştırmaz.
Probe ProbePolicy
/*
* FreshenRoles, oturum AÇILIRKEN kullanıcının rollerini aktif kimlik
* kaynağından tazeler. nil ise tazeleme yapılmaz.
*
* ⚠️ NEDEN BURADA: iki kapı (SSH kanalı ve web terminali) tek
* fonksiyondan geçiyor, yani kural ikisine birden uygulanıyor —
* "iki kapı, tek gerçek". Kimlik doğrulama geri çağrısında değil,
* çünkü orası el sıkışmanın içi: bir handshake'te birden çok kez
* çağrılıyor ve orada ağ isteği yapmak, kimliği doğrulanmamış bir
* bağlantıyı dizine karşı bir yükseltici hâline getirirdi.
*
* ErrDirectoryRefused dönerse oturum REDDEDİLİR; başka bir hata
* yalnızca loglanır ve saklanan rollerle devam edilir (dizin arızası
* yetki yokluğu değildir).
*/
FreshenRoles func(ctx context.Context, username string) error
// Events, canlı izleme akışı. nil ise olay yayınlanmaz.
//
// ⚠️ Publish BLOKLAMAZ (bkz. events.Bus): burası bir oturumun açılış
// ve kapanış yolu ve izleyen bir panel, izlediği oturumu
// bekletemez.
Events events.Publisher
// Live, akan oturumların defteri: yöneticinin kesme düğmesi buradan
// çalışıyor. nil olabilir — o zaman kayıt tutulmuyor ve hiçbir
// oturum kesilemiyor (Live'ın bütün metotları nil-güvenli).
Live *Live
}
Deps, oturum açmak için gereken altyapı. Hem sshd.Server hem httpapi.Server bunu kurar.
type ExecRequest ¶
type ExecRequest struct {
Command string
}
ExecRequest, "exec" payload'ı (RFC 4254 §6.5).
func ParseExec ¶
func ParseExec(payload []byte) (ExecRequest, error)
ParseExec parses an "exec" payload.
type Live ¶
type Live struct {
// contains filtered or unexported fields
}
Live, akan oturumların id -> iptal eşlemesi.
func (*Live) RunningIDs ¶
RunningIDs, bu süreçte akan oturumların kimlikleri.
Panel, veritabanındaki "açık" satırları bununla süzüyor: açık ama akmayan satır, çökmeden kalmış bir izdir ve "çalışıyor" diye gösterilmemeli.
func (*Live) Terminate ¶
* Terminate, oturumu keser ve KESTİĞİNİ bildirir. * * Dönen false "böyle akan bir oturum yok" demek — çağıran bunu * "kesildi" diye çevirmemeli. Bu ayrım, bu dosyanın var olma sebebi. * * ⚠️ SEBEP KİMİ İÇERİYOR. context.Cause zincirinden okunan metin * doğrudan denetim satırına ve kullanıcıya giden cümleye dönüşüyor; * "kesildi" ile "yönetici admin kesti" arasındaki fark, olay sonrası * kaydı okuyan için işin tamamı. errors.Is(ErrTerminated) yine * çalışıyor, çünkü sarmalıyoruz.
func (*Live) TerminateAll ¶
* TerminateAll, akan bütün oturumları verilen sebeple keser ve kaç * tanesini kestiğini döner. * * ⚠️ KAPANIŞIN SON ADIMI. Bekleme süresi dolduğunda çağrılıyor: * oturumları öylece bırakıp süreçten çıkmak, kaydı yarım ve arşiv * kuyruğuna hiç girmemiş hâlde bırakmak demekti. Buradan geçen her * oturum normal kapanış yolunu yürüyor — kullanıcı sebebini görüyor, * kayıt kapanıyor, Close arşivi kuyruğa yazıyor. * * ⚠️ KOPYA ÜZERİNDE GEZİLİYOR. cancel çağrıları Run'ın kendi * goroutine'lerini uyandırıyor ve onlar remove'a giriyor; defterin * kilidini tutarken iptal etmek kilitlenme demekti (Terminate'teki * notun aynısı).
type ProbePolicy ¶
* ProbePolicy, tanımanın açık olup olmadığı ve sınırları. * * Sıfır değeri KAPALI ve bu kasıtlı: yapıyı sıfır değeriyle kuran her * çağıran (testler dahil) hedefe dokunmayan davranışı alır.
type PtyRequest ¶
type PtyRequest struct {
Term string
Columns, Rows uint32
Width, Height uint32 // piksel cinsinden; genelde 0
Modes string // opaque terminal modes — parse etme, olduğu gibi ilet (Ek C.4)
}
PtyRequest, "pty-req" payload'ı (RFC 4254 §6.2).
func ParsePty ¶
func ParsePty(payload []byte) (PtyRequest, error)
ParsePty parses a "pty-req" payload.
type Request ¶
type Request struct {
// Username, DOĞRULANMIŞ postern kullanıcı adıdır — istemcinin iddia
// ettiği değil. SSH tarafında Permissions'tan, web tarafında oturum
// kaydından gelir; ikisi de kimliği kendi kapısında doğrulamış olur.
Username string
/*
* AccountID, bağlantının bağlı olduğu users.id.
*
* ⚠️ AD DEĞİL KİMLİK, VE BOŞ GEÇİLEMİYOR. Ad yeniden
* kullanılabiliyor (purge onu serbest bırakıyor), kimlik kalıcı.
* Bunu kapıda çözüp buraya taşımak, kanal açılırken "bu bağlantı
* HÂLÂ o kişiye mi ait" sorusunun sorulabilmesinin tek yolu.
*/
AccountID string
TargetName string
SrcIP string
}
Request, açılacak oturumun kim/nereye bilgisi.
type RequestPolicy ¶
type RequestPolicy struct {
// AcceptEnv, geçmesine izin verilen ortam değişkeni adları.
// Sondaki * joker: "LC_*" tüm LC_ ile başlayanları kapsar.
//
// nil = varsayılan (defaultAcceptEnv). BOŞ DİLİM = hiçbiri; ikisi
// farklı şeyler ve YAML bu ikisini ayırt edebiliyor.
AcceptEnv []string
/*
* AllowSFTP, `subsystem sftp` kanalını açar.
*
* ⚠️ VARSAYILAN KAPALI ve öyle kalmalı. Açık geldiğinde, yükseltme
* yapan bir operatör hiçbir şey yapmadan yeni bir veri çıkış yolu
* kazanmış olurdu — üstelik farkında olmadan.
*
* Açıkken bile SFTP yalnızca dosya olayları denetlenerek geçiyor
* (sftp.go). Denetim kurulamıyorsa kanal AÇILMIYOR: bu bayrağın
* anlamı "sftp serbest" değil, "denetimli sftp serbest".
*/
AllowSFTP bool
}
RequestPolicy, oturum kanalı request'lerinin geçiş kuralları.
type SFTPSink ¶
SFTPSink, üretilen dosya olaylarının gideceği yer.
Emit veri yolundan çağrılıyor: yavaş olmamalı. Kalıcılaştırma (veritabanına yazım) çağıranın işi.
type Session ¶
type Session struct {
// ID, denetim satırının ve .cast dosyasının ortak anahtarı.
ID string
// OSUser, policy'nin verdiği karar — çağıran log'a yazsın diye açık.
OSUser string
// Log, oturumun alanları bağlanmış logger'ı (user, target, session_id,
// record_path). Çağıran kendi olaylarını bununla yazsın ki satırlar
// aynı oturumda birleşsin.
Log *slog.Logger
// contains filtered or unexported fields
}
Session, açılmış ama henüz sürülmemiş bir oturum: hedefe bağlanılmış, kayıt dosyası açılmış, denetim satırı yazılmıştır. Run ile sürülür, Close ile kapatılır.
func Open ¶
Open, yetkiyi denetler ve oturumu hedefe kadar kurar.
Hata döndüğünde HİÇBİR ŞEY açık kalmaz: kısmi kurulum kendi içinde temizlenir ve dönen Session nil'dir — çağıranın Close çağırmasına gerek yoktur.
func (*Session) Close ¶
Close, oturumu kapatır: kayıt dosyası, denetim satırı, hedef bağlantısı. İkinci çağrı no-op — çağıran defer'la koyabilsin diye.
type WindowChangeRequest ¶
WindowChangeRequest, "window-change" payload'ı (RFC 4254 §6.7).
func ParseWindowChange ¶
func ParseWindowChange(payload []byte) (WindowChangeRequest, error)
ParseWindowChange parses a "window-change" payload.