Pochopte, / etc / inittab
On 12 února, 2021 by admin Používám následující /etc/inittab
soubor (systemv):
# /etc/inittab: init(8) configuration. # $Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $ # The default runlevel. id:5:initdefault: # Boot-time system configuration/initialization script. # This is run first except when booting in emergency (-b) mode. si::sysinit:/etc/init.d/rcS # What to do in single-user mode. ~~:S:wait:/sbin/sulogin # /etc/init.d executes the S and K scripts upon change # of runlevel. # # Runlevel 0 is halt. # Runlevel 1 is single-user. # Runlevels 2-5 are multi-user. # Runlevel 6 is reboot. l0:0:wait:/etc/init.d/rc 0 l1:1:wait:/etc/init.d/rc 1 l2:2:wait:/etc/init.d/rc 2 l3:3:wait:/etc/init.d/rc 3 l4:4:wait:/etc/init.d/rc 4 l5:5:wait:/etc/init.d/rc 5 l6:6:wait:/etc/init.d/rc 6 # Normally not reached, but fallthrough in case of emergency. z6:6:respawn:/sbin/sulogin S0:12345:respawn:/sbin/getty -L 115200 ttyS0
Abychom pochopili, jak věci skutečně fungují, oceníme, když vaše odpovědi na 1-3 rozlišujete mezi dvěma situacemi:
- Jsem připojen k mému systému pomocí sériového portu.
- Mám „běžný“ stolní počítač.
Dotazy:
-
Pokud přidám další getty linku, po spuštění linuxu uvidím dva samostatné terminály?
-
Pokud otevřu několik getty linek, jak jsem přiřadil které getty spustí můj
si::sysinit:/etc/init.d/rcS
příkaz a který getty bude spouštět příkazy ostatních skriptů? (ti, kteří spouštějí skripty podle úrovně běhu systému)v jinými slovy: v souboru
/etc/inittab
– mohu přiřadit různé příkazy různým gettys? (myslím terminálům, které se pomocí těchto gettys otevřou) -
poslední skript ve složce /etc/init.d/rc5 spuštěn následující příkaz:
su nobody -c /bin/sh
a výstup je:
sh: cannot set terminal process group (1618): Inappropriate ioctl for device sh: no job control in this shell sh-4.3$ whoami nobody
Takže jsem ověřil že nejsem nikdo, ale proč píše první dva řádky? také důvod, proč je výzva sh-4.3 $ a ne nikdo @ …
-
Používám sériové připojení. Mohu změnit soubor / etc / inittab a poslední skript který bude spuštěn programem init za účelem:
- spuštění programu před přihlášením jako uživatele s nízkými oprávněními (proces init bude čekat na ukončení)
- po ukončení programu získáte pravidelný výzva k přihlášení do mého systému
- jaký je nejlepší způsob, jak vytvořit uživatele s nízkými oprávněními a nechat ho spustit tento program během procesu inicializace (pokud nechci použít nikoho uživatele)
Odpověď
Otázka 1:
Ano, přidáním dalších getty
řádky můžete získat více terminálů paralelně. K jednomu koncovému zařízení lze současně přidružit pouze jeden getty
, takže na jeden sériový port je možný pouze jeden getty
. Na běžném stolním počítači definuje linuxové jádro řadu virtuálních konzolí, které jsou přístupné pomocí kombinací kláves Control + Alt + FX a odpovídají /dev/ttyX
zařízení (X = číslo). Přesné nastavení se může u různých distribucí lišit, ale obvykle u mainstreamových distribucí je prvních asi 6 /dev/ttyX
zařízení pro ně getty
nakonfigurováno, když systém běží normálně. Můžete použít openvt
a deallocvt
příkazy k přidání nebo odebrání virtuálních konzolí a spuštění procesů (což mohou být jakékoli procesy, ne nutně getty
s) na nich.
/dev/tty0
je speciální: týká se jakékoli virtuální konzoly, která je aktuálně vybraná. /dev/console
je podobné speciální zařízení, které ukazuje na jakékoli zařízení TTY, které je definováno jako primární systémová konzole na úrovni jádra. V systémech pro stolní počítače je to ve výchozím nastavení alias /dev/tty0
, ale pomocí spouštěcí možnosti console=
jej můžete přepnout na sériové přístav. Na např. u některých integrovaných architektur to může být ve výchozím nastavení sériový port. Obslužné programy jako xconsole
mohou také fungovat jako další výstup pro /dev/console
.
Když byly počítače ve specializovaných počítačových místnostech velké věci s více skříněmi, bylo by zaslání zprávy /dev/console
způsobem, jak se obrátit na provozovatele systému ve službě fyzicky blízko počítače, což by mohlo být užitečné pro požadavky např vyměňte pásky nebo diskové sady. V moderních systémech jsou zprávy odesílané konkrétně na /dev/console
obvykle spouštěcí / vypínací zprávy, případně kanál poslední instance pro naléhavé alarmy týkající se poruchových podmínek, které by mohly ovlivnit přístup k síti nebo úložišti, nebo dokonce zahrnout havárii jádra: „osoba odpovědná za fyzický hardware to musí vidět a obvyklé soubory protokolu jsou z nějakého důvodu nepoužitelné.“
Otázka 2:
Obávám se, že zde máte mylnou představu. Řádek sysinit
a další řádky /etc/inittab
nejsou spojeny s getty
procesy vůbec. Každý příkaz spuštěný z inittab
, pokud není uvedeno jinak, má své standardní vstupní, výstupní a chybové toky spojené s /dev/console
.
Řádky getty
ve skutečnosti určují zařízení TTY, které budou používat, a proces getty
má zabudovaný kód, který přiřadí toto zařízení TTY sobě a všechny jejich podřízené procesy, pokud / dokud uživatel nespustí shell a nerozhodne se tyto proudy přesměrovat jiným způsobem.Toto a inicializace nastavení zařízení TTY jsou největší částí účelu getty
„: zobrazení /etc/issue
a výzvy k přihlášení, přijetí uživatelské jméno, nastavení proměnné prostředí TERM a zahájení dalšího kroku procesu přihlášení TTY (obvykle /bin/login
, ale přizpůsobitelného) jsou ve skutečnosti jen malé části.
Všimněte si, že tam je konvence, že u zařízení TTY by se dvoumístné pole ID v prvním sloupci řádku inittab
mělo shodovat s názvem dotyčného zařízení TTY po /dev/tty
předponu, takže /dev/ttyS0
získá ID řádku inittab S0
atd. Pro věci, které nemusí být nutně asociován s jakýmkoli TTY (nebo v případě potřeby pouze odesílá nouzové věci do / dev / console), ID může být cokoli, co není v rozporu s ID řádku zařízení TTY.
(Zpět v den, kdy byly sériově připojené terminály č rm, získání nastavení zařízení TTY přímo pro terminál na druhém konci linky a resetování tohoto terminálu do známého stavu pro přihlášení byly netriviální úkoly, protože existovalo mnoho konkurenčních standardů typu terminálu.)
Pokud nakonfigurujete řádek inittab
pro spuštění skriptu, můžete například zjistit, zda konkrétní /dev/ttyX
virtuální konzole zařízení existuje. Pokud tomu tak není, můžete pomocí openvt -c X <command>
vytvořit virtuální konzoli a spustit na ní příkaz; pokud zařízení virtuální konzoly již existuje, můžete jednoduše spustit libovolný požadovaný příkaz se standardním vstupem, výstupem a chybou přesměrovanou na něj. Můžete například zadat řádek inittab takto:
6:345:respawn:/usr/local/sbin/myscript
a poté /usr/local/sbin/myscript
něčím podobným ( odmítnutí odpovědnosti: netestováno, nemám nyní po ruce systém se SysVinitem, neváhejte jej upravit, pokud to můžete vylepšit):
#!/bin/sh if [ -c /dev/tty6 ]; then exec <some command> </dev/tty6 >/dev/tty6 2>&1 else exec openvt -c 6 -w <some command> fi
respawn
v řádku inittab
zajišťuje, že proces bude automaticky restartován, pokud z jakéhokoli důvodu zemře. 345
je seznam úrovní běhu SysVinit, na kterých by tento proces měl běžet. Pokud potřebujete, aby běžel na všech běžných úrovních běhu, zadejte 12345
.
Poznámka funguje, jak bylo zamýšleno, pouze pokud je řádek inittab umístěn za řádek sysinit
, takže lze předpokládat, že inicializace udev
je úplná. chcete to udělat na začátku procesu inicializace, možná se budete muset postarat o vytvoření skutečných uzlů zařízení pro zařízení, která mají ovladače načtené jako první; jakmile je udev
spuštěn, měl by automaticky vytvářet uzly zařízení při inicializaci ovladačů zařízení.
Pokud používáte sériový port, openvt
se nepoužije.
Takže ano, určitě můžete připojit různé příkazy k různým zařízením TTY. Pomůže to, pokud mají příkazy vestavěné funkce, jako getty
s, ale můžete to udělat i se skriptováním.
(Pokud nastavíte něco složitějšího než jednoduché tail -f
pro trvalé zobrazení nějakého protokolu v jinak nepoužívané virtuální konzole, měli byste si přečíst man setsid
a zjistěte, zda je použitelné pro to, co plánujete.)
Otázka 3:
Inicializace relace TTY má ještě víc pro konkrétního uživatele bez oprávnění root než pouhé spuštění shellu pomocí su
.
Chybové zprávy
sh: cannot set terminal process group (1618): Inappropriate ioctl for device sh: no job control in this shell
jsou pravděpodobně způsobeny tím, že je shell přidružen zařízením /dev/console
než konkrétním zařízením TTY. Protože /dev/console
je pouze alias jakékoli aktuální konzoly systému, nebude mít k dispozici úplnou sadu ovládacích funkcí ioctl TTY.
Pokud neexistuje přihlašovací skript pro přiřazení užitečnější hodnoty proměnné prostředí PS1
, zobrazí se výchozí výzva pro /bin/sh
může být jednoduše sh-<version>$
.
Otázka 4:
Ano, můžete. „Poslední skript“ byste měli zadat jako wait
-typový řádek v inittab
a umístit jej před getty
řádek odpovídající vaší sériové lince.
Bez znalosti dalších podrobností o vašem prostředí bude velmi obtížné říci, který by byl nejlepší způsob, jak pro tyto účely vytvořit uživatele s nízkými oprávněními.
Komentáře
odpověď
-
Ano, za předpokladu, že řádek dostane jedinečný identifikátor a nakonfigurovaná svorkovnice je k dispozici:
S1:12345:respawn:/sbin/getty -L 115200 ttyS1
otevře terminál na sériovém portu připojeném k
ttyS1
. -
Řádky v
inittab
nejsou sekvenční ani nesouvisí s přihlášením. Každý řádek popisuje akci, která má být provedena v dané sadě úrovní běhu.si::sysinit:/etc/init.d/rcS
tedy určuje, žeinit
by měl při zpracování inicializace systému běžet/etc/init.d/rcS
; to se děje dříve, než je možné přihlášení. (Podrobnosti viz nainittab(5)
stránce ).Přiřazení různých příkazů různým
getty
s na konkrétních terminálech byste nakonfigurovali samotnégetty
volání, například změnoulogin
program, který se spouští (možnost-l
ve většiněgetty
implementací):S0:12345:respawn:/sbin/getty -L 115200 -l /bin/my-t0-login ttyS0 S1:12345:respawn:/sbin/getty -L 115200 -l /bin/my-t1-login ttyS1
-
/etc/init.d/rc 5
běží dříve, než je možné přihlášení, a spuštěné programy nejsou připojeny k terminálu („správně“, což je to, cogetty
dělá – otevře vám terminál a připojí k němu spuštěné programy), takže když jesu nobody -c /bin/sh
vyvolán, shell nenajde očekávané nastavení terminálu a ve výsledku deaktivuje řízení úlohy. Výzvash-4.3$
je výchozí výzva Bash 4.3 při spuštění jako/bin/sh
. -
Pokud má váš program běžet až poté, co se uživatel začne přihlašovat, můžete jej připojit do přihlašovací sekvence, kterou používá
getty
; ale takový program by fungoval jako root. V závislosti na tom, co přesně sledujete, pravděpodobně by bylo lepší použít initscript než přizpůsobení/etc/inittab
nebosudo
a spouštěcí skripty prostředí.
Komentáře
- děkujeme za vaše přehrání. Mohu požádat o vysvětlení smailu ohledně sek.2? jak mohu upravit přihlašovací příkaz pro každý jiný getty?
- Hotovo, podívejte se na aktualizaci.
- děkuji! jen zkontrolovat, zda jsem správně pochopil: ve výchozím nastavení spustí proces getty příkaz / bin / login, který provede proces odpovědný za přihlášení do systému. Nyní getty spustí jiný příkaz, každý příkaz, který si ‚ vyberu a nezavolá proces přihlášení do systému jako předtím … mám pravdu?
- Ano, je to tak. Klíčem je
getty
otevřít vám TTY; jeho obvyklým chováním je čekat na přihlašovací jméno a poté spustitlogin
připojený k TTY;login
čeká na heslo, zkontroluje jej a spustí shell, rovněž připojený k TTY. Pokud nahradíte částlogin
, budete muset zajistit, aby se váš náhradní program choval jakologin
. - Například pokud chci přeskočit přihlašovací fázi – abych mohl otevřít svůj systém s rootem bez zadání jakéhokoli uživatelského jména nebo hesla. Mohu použít: S0: 12345: respawn: / sbin / getty -L 115200 -l – / bin / sh ttyS0 nebo použít: S0: 12345: respawn: / sbin / getty -L 115200 -l [my_script_path] ttyS0 a uvnitř skript ‚ spustím příkaz – / bin / sh a další?
Odpovědět
Právě teď vteřinu (dlouho!) odpověď byla zveřejněna. Musím říci, že první vysvětluje docela dobře. V tuto chvíli se chci vyjádřit k bodu tři: Jde spíše o načasování, ale o procesy ovládající „skutečnou virtuální“ tty, a ne jen o „konzolovou figurínu“.
Než budete moci spustit shell „s ovládáním úlohy“, musíte nastavit, tj. otevřít ttyN. Obecný příkaz je getty
. Z toho tty-něčeho, co získáte, můžete spustit shell, nejen poté .
Je to jako pokusit se nejprve spustit správce oken a poté xorg, místo toho je „zavádět“ společně s xinit. Myslím. „leader leader“.
Z důvodu
xx:12:...:program
a naopak:
aa:1:...:pr_1 bb:1:...:pr_2
… získáte relaci N: M (při zneužití získáte také nepořádek – mnoho RL, každý s mnoha různými progry). S tím můžete zajít daleko, ale od té doby se ujaly různé druhy RC- „standardů“. „Runcoms“. S nimi vypadá inittab jednoduše, ale složitost je v těchto skriptech.
Ale váš inittab vypadá jednoduše a správně – pouze poslední komentář a položka „z6“ …
Možná, že vaše „su nobody“ potřebuje „getty … ttyN“ před / kolem. su
místo login
a žádný respawn. Mělo by přinejmenším poskytnout další chybovou zprávu než „nevhodnou“.
Závěr (po přečtení 2. odpovědi): Nepotřebujete komplikovaný init.d
systém, raw inittab je dostatečně flexibilní. Stačí se dostat koncept a podrobnosti správně.
Mohli byste nastavit tři úrovně běhu: jednu s ttyNs, jednu s ttySN a jednu RL, která spouští obě. Jedná se o spouštěcí parametr, který můžete přidat pomocí zavaděče. „5“ je ve vašem případě pouze výchozí. Vyberete jádro, root = a runlevel, do kterého se má inicializovat.
Akce „respawn“ je to, k čemu je / je ve skutečnosti sysvinit . Mnohem více to nedělá a méně by bylo možné implementovat ve skriptu. Pokud ale opustíte (nebo narazíte) na „poslední“ úroveň shellu, potřebujete bezpečnostní síť.
sysvinit může dokonce odhalí chybnou konfiguraci chybou „příliš rychle se rozmnoží – ignoruje se po dobu 5 minut …“.
getty
je proces; o čem mluvíte, je zařízení TTY . Jádro otevřelo první pro vás a pro init skripty;/dev/console
je alias “ prvního zařízení TTY, které bylo otevřeno a používáno jádrem „. Pokud má váš uživatelský účet oprávnění pro přístup ke čtení a zápisu na zařízení TTY, můžete jej jednoduše začít používat (nenígetty
potřeba), ale může být dobrý nápad nastavit Proměnná TERM správně:TERM=linux top </dev/tty8 >/dev/tty8 2>&1 &
neboTERM=vt100 top </dev/ttyS1 >/dev/ttyS1 2>&1 &
spustí příkaztop
na 8. virtuální konzoli nebo 2. sériový port.getty
proces, udělá to nepořádek výstup &, protože tyto dva procesy budou bojovat o vstup a jejich výstupy budou smíchány dohromady. Procesygetty
jsou spuštěny až po/etc/init.d/rc 5
a všech jimi spuštěných skriptech dokončeny .