Dale Hagglund yerinde. Bu yüzden ben sadece aynı şeyi söyleyeceğim ama farklı bir şekilde, bazı özellikleri ve örnekleri ile. ☺
Unix ve Linux dünyalarında yapılacak doğru şey:
- süper kullanıcı olarak çalışan ve dinleme soketini bağlayan küçük, basit, kolay denetlenebilir bir programa sahip olmak;
- ilk programın doğurduğu, ayrıcalıkları azaltan başka bir küçük, basit, kolay denetlenebilir bir programa sahip olmak;
- hizmet etinin ayrı bir üçüncü programda, süper kullanıcı olmayan bir hesap altında çalıştırılması ve ikinci program tarafından yüklenen zincirin çalıştırılması, soketin açık bir dosya tanımlayıcısının basitçe miras kalmasını beklemek.
Yüksek riskin nerede olduğu konusunda yanlış bir fikriniz var. Yüksek risk, ağdan okuma ve basit bir sokette açılış, bir limana bağlama ve çağrı yapma eylemlerinde okunmayanlara göre hareket etmektir listen(). Yüksek riskli gerçek iletişimi yapan bir hizmetin parçası. Açmak, parça bind()ve listen()o (bir ölçüde) bile bir kısmını ve accepts()yüksek riskli değildir ve süper şemsiyesi altında çalıştırılabilir. accept()Ağ üzerindeki güvenilmeyen yabancıların kontrolü altında olan verileri kullanmazlar (kaynak IP adresleri hariç ).
Bunu yapmanın birçok yolu var.
inetd
Dale Hagglund'in dediği gibi, eski "ağ sunucusu" inetdbunu yapar. Hizmet işleminin yürütüldüğü hesap, içindeki sütunlardan biridir inetd.conf. Dinleme parçasını ve bırakma ayrıcalıklarını, küçük ve kolayca denetlenebilen iki ayrı programa ayırmaz, ancak ana servis kodunu, exec()açık bir dosya tanımlayıcı ile ortaya koyduğu bir servis sürecinde ayrı bir programa ayırır. soket için.
Denetim zorluğu, bir programı yalnızca denetlemek zorunda olduğu için çok fazla bir sorun değildir. inetden önemli sorun çok fazla denetim yapmak değil, daha ziyade araçlara kıyasla basit ince taneli çalışma zamanı servis kontrolü sağlamadığıdır.
UCSPI-TCP ve Daemontools
Daniel J. Bernstein'in UCSPI-TCP ve daemontools paketleri birlikte kullanılmak üzere tasarlandı. Alternatif olarak, Bruce Guenter'ın büyük ölçüde eşdeğer daemontools-encore araç setini kullanabilirsiniz.
Soket dosya tanımlayıcısını açma ve ayrıcalıklı yerel bağlantı noktasına bağlama programı, tcpserverUCSPI-TCP'dir. Hem yapar listen()ve accept().
tcpserverSonra ya (protokol sunulmakta çünkü örneğinde olduğu gibi, "oturum" sonra süper kullanıcı olarak başlayan ve içerir, örneğin bir FTP veya bir SSH programı) kök ayrıcalıkları kendisi düşer veya bir hizmet programı olarak çoğaltılır setuidgidbir olduğunu Yalnızca ayrıcalıkları düşüren ve ardından hizmet programına zincir yükleri yükleyen kendi kendine yeten küçük ve kolayca denetlenebilir bir program (bu nedenle hiçbiri hiçbir zaman süper kullanıcı ayrıcalıklarıyla çalışmaz qmail-smtpd).
runBöylece bir servis betiği şöyle olabilir ( boş IDENT servisi sağlamak için bu kukla için):
#!/bin/sh -e
exec 2>&1
exec \
tcpserver 0 113 \
setuidgid nobody \
dummyidentd.pl
nosh
Hayır paketim bunu yapmak için tasarlandı. Tıpkı setuidgiddiğerleri gibi küçük bir yardımcı programı var. Küçük bir fark, systemdstil "LISTEN_FDS" hizmetlerinin yanı sıra UCSPI-TCP hizmetlerinde de kullanılabilir olması, bu nedenle geleneksel tcpserverprogram iki ayrı programla değiştirildi: tcp-socket-listenve tcp-socket-accept.
Yine, tek amaçlı yardımcı programlar doğar ve zincirler birbirlerini yükler. Tasarımın ilginç yönlerinden biri, süper kullanıcı ayrıcalıklarını listen()daha önce veya daha önce bırakmasıdır accept(). İşte bunun runiçin bir senaryo qmail-smtpdtam olarak bunu yapar:
#!/bin/nosh
fdmove -c 2 1
clearenv --keep-path --keep-locale
envdir env/
softlimit -m 70000000
tcp-socket-listen --combine4and6 --backlog 2 ::0 smtp
setuidgid qmaild
sh -c 'exec \
tcp-socket-accept -v -l "${LOCAL:-0}" -c "${MAXSMTPD:-1}" \
ucspi-socket-rules-check \
qmail-smtpd \
'
Süper himayesinde yürütülmektedir programlar küçük hizmet agnostik zincir yükleme araçlardır fdmove, clearenv, envdir, softlimit, tcp-socket-listen, ve setuidgid. Başlanan noktaya shkadar soket açık ve smtplimana bağlı ve işlem artık süper kullanıcı haklarına sahip değil.
s6, s6 ağı ve execline
Laurent Bercot'un s6 ve s6 ağ paketleri, bunu birlikte yapacak şekilde tasarlanmıştır. Komutlar yapısal olarak daemontoolsve UCSPI-TCP'ye çok benzer .
runkomut konması dışında, hemen hemen aynı olacaktır s6-tcpserveriçin tcpserverve s6-setuidgidiçin setuidgid. Bununla birlikte, bir kişi M. Bercot'un yürütme araç setini aynı anda kullanmayı da seçebilir .
İşte Wayne Marshall'ın orijinalinden hafifçe değiştirilmiş, execline, s6, s6-networking ve publicfile'den FTP sunucusu programını kullanan bir FTP servisine örnek :
#!/command/execlineb -PW
multisubstitute {
define CONLIMIT 41
define FTP_ARCHIVE "/var/public/ftp"
}
fdmove -c 2 1
s6-envuidgid pubftp
s6-softlimit -o25 -d250000
s6-tcpserver -vDRH -l0 -b50 -c ${CONLIMIT} -B '220 Features: a p .' 0 21
ftpd ${FTP_ARCHIVE}
ipsvd
Gerrit Pape en ipsvd ucspi-tcp ve s6-ağ ile aynı doğrultuda çalışan başka araç setidir. Araçlar chpstve tcpsvdbu sefer, ama aynı şeyi yapıyorlar ve güvenilmeyen istemciler tarafından ağ üzerinden gönderilen şeylerin okunması, işlenmesi ve yazılmasını yapan yüksek riskli kod hala ayrı bir programda.
İşte M. Pape'infnord bir runsenaryoda yayınlanması örneği :
#!/bin/sh
exec 2>&1
cd /public/10.0.5.4
exec \
chpst -m300000 -Uwwwuser \
tcpsvd -v 10.0.5.4 443 sslio -v -unobody -//etc/fnord/jail -C./cert.pem \
fnord
systemd
systemdBazı Linux dağıtımlarında bulunabilir yeni hizmet denetim ve init sistemi, ne amaçlanmaktadır inetdyapabilirsiniz . Ancak, küçük kendi kendine yeten programlar paketi kullanmaz. Kişi systemdne yazık ki bütünüyle denetlemek zorunda .
İle systemdbiri soket tanımlamak için yapılandırma dosyaları oluşturur systemddinler ve bir hizmeti systemdbaşlatır. Servis "birim" dosyası, hangi kullanıcı olarak çalıştığı da dahil olmak üzere servis işlemleri üzerinde büyük bir kontrol sağlamasına izin veren ayarlara sahiptir.
Bu kullanıcı süper kullanıcı olmayan bir kullanıcı olarak ayarlanmışsa systemd, soketin açılması, bir bağlantı noktasına bağlanması ve # 1 işleminde süper kullanıcı olarak çağırılması listen()(ve gerekirse accept()) ve kullanıcı tarafından servis işleminin yapılması spawns, kullanıcı ayrıcalığı olmadan çalışır.