亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Linux會話淺析

2019-11-11 05:02:36
字體:
來源:轉載
供稿:網友
說起會話,我們經常登錄到linux系統,執行各種各樣的程序,這都牽涉到會話。但是,一般情況下我們又很少會去關注到會話的存在,很少會去了解它的來龍去脈。本文就對linux會話相關的信息做一些整理,看看隱藏在我們日常使用的背后,都有些什么樣的邏輯?!緯挼木S系】維系一個會話,最常見的有兩種方式:一是基于某種憑證,比如web網站的登錄會話,在登錄驗證之后,服務器就會返回一個session id作為憑證。用戶之后的請求總是會帶上這個id,而服務器通過這個id也就能知道用戶是誰。直到用戶注銷登錄、或者登錄超時,服務器會清洗掉對應的session id,這個id就失效了,會話也就隨之而結束。第二種方式是基于連接的,當用戶和系統之間的連接啟用時,系統會對用戶進行驗證,驗證通過之后,來自這個連接的操作都是屬于這個用戶的。直到連接斷開,則會話結束。linux系統的會話就是以第二種方式來維系的。會話基于連接,那么連接的安全性就決定了會話的安全性。以最常見的兩種連接為例:1、本地連接,用戶是直接通過鍵盤顯示器來跟系統交互的,鍵盤顯示器直接連接在主機上,連接被篡改基本上是不可能的;2、遠程連接,以ssh為例,其協議會進行加密,從而避免連接被篡改;下面在討論會話的時候就圍繞兩種連接來展開?!具B接的啟用】前面說到,會話是基于連接的。會話的源頭,就是用戶與系統之間連接的啟用。對于本地連接,連接是在系統初始化時建立的。linux會初始化若干個tty(/dev/tty?),形成若干個虛擬終端。本地連接的鍵盤和顯示器通過對應的驅動程序,跟其中某個tty綁定上。用戶可以通過ALT+F[1-12]鍵,將鍵盤和顯示器切換到不同的tty上(也就是說,一套鍵盤顯示器可以對應多個本地連接)。在系統啟動的時候,init程序會根據相應的配置(如:/etc/init/tty1.conf),啟動相應的程序來監聽這些tty(如:/sbin/getty -8 38400 tty1。下文說到這個監聽程序時,就以getty為例)。當用戶通過ALT+F?切換到對應的tty?、并有所輸入時,在該tty上監聽的getty就能讀取到輸入信息,然后通過exec啟動login程序來進行登錄驗證。從getty得到輸入的這一刻起,tty?上的這個連接就算是啟用了。對于遠程連接,本文都以ssh為例。系統安裝ssh server之后,在/etc/init.d/下會有它對應的啟動腳本,這會使得sshd程序(ssh服務器)在系統啟動的時候被啟動(當然,root用戶也可以在系統啟動之后,手動啟動sshd)。sshd監聽網絡上的相應端口(如:tcp:22),等待遠程用戶的連接。用戶的連接始于TCP連接,然后sshd和ssh-client會打通ssh隧道。從這時起,連接啟用,sshd會要求用戶進行登錄驗證?!镜卿涷炞C】不管是本地終端登錄,還是遠程登錄,登錄驗證無非就是要讓用戶輸入用戶名和密碼。用戶輸入的信息通過已經啟用的連接到達對端程序(如:login、sshd),然后由其進行校驗。系統中的用戶信息存放在/etc/passwd文件中,里面保存的系統中所有用戶的信息。這些信息主要有:用戶名、密碼、組、home路徑、以及登錄后執行的程序、等。這些信息可以分兩個層面來看:一、用于驗證的。包括用戶名和密碼兩項。即用戶在與系統建立連接后,需要提供用戶名和密碼來進行驗證(注意,密碼一般并不是明文保存在passwd文件中的);二、登錄后用于設置用戶屬性的。除密碼外的所有項。下面會詳細解釋;用戶登錄后會得到一個進程,關于這個進程,它有如下一些特征:1、對于本地連接,它就是原本執行getty的那個進程;而對于ssh連接,它是由sshd fork出來的進程;2、進程的用戶名、組、當前路徑、等都被按/etc/passwd文件中的描述進行設置;3、進程的stdin、stdout、stderr連接到一個對應的終端。對于本地連接,這個終端就是getty監聽的那個tty;對于ssh連接,它是由sshd打開的pty(偽終端,后面會詳細解釋);4、這個進程會執行/etc/passwd中配置的"登錄后執行的程序",這個程序一般就是/bin/sh,即登錄后為用戶提供一個shell控制臺。于是用戶可以使用自己的終端跟這個shell程序交互,干各種事情。這個"登錄后執行的程序"也常被配置為/bin/nologin,表示對應用戶是不允許登錄的,因為nologin程序不會與用戶進行交互,打印錯誤信息后就會退出了,所以登錄只是白費勁。當然,如果你愿意,并且有root權限,也可以將"登錄后執行的程序"配置成其他程序;于是,用戶在登錄完成之后,系統中就存在這樣一個用戶名為該登錄用戶的進程。通常這個進程運行shell程序,并且其輸入輸出連接到用戶的終端,所以用戶可以用鍵盤來操作這個shell,并且用顯示器接收shell的輸出?!娟P于終端】前面講到,登錄后的shell其輸入輸出是連接到用戶使用的終端的,不管是本地登錄的tty,還是遠程登錄的pty。但是,為什么要有終端呢?shell的輸入直接接到鍵盤、輸出直接接到顯示器,這樣不行么?尤其是遠程的情況,shell的輸入輸出為什么不能直接接到網絡,而非要弄一個pty出來呢?最容易想到的一點,終端能夠使得上層不必關心輸入輸出設備本身的細節,只管對其讀寫就行了。不過這一點似乎并不是終端所特有的,因為vfs已經能夠勝任了。應用程序open設備文件,得到fd,然后同樣只用管對其讀寫就行了,而不用關心這個fd代表的是鍵盤、還是普通文件,具體的細節已經被隱藏在設備驅動程序之中。不過,相比于普通的讀寫,終端還實現了很多可以通過ioctl系統調用進行配置的功能,能夠完成一些針對輸入輸出的處理邏輯。如:1、回車換行的轉換:定義輸入輸出如何映射回車換行符。比如:回車鍵是/r、還是/n、還是/r/n;再如:/n應該如何打印到屏幕上,是回車+換行、還是只換行不回車、等等;2、行編輯:允許讓輸入字符不是立馬送到應用程序,而是在換行以后才能被讀取到。未換行的輸入字符可以通過退格鍵進行編輯(比如在你密碼輸錯的時候,是可以用CTRL+退格來進行編輯的);3、回顯:可以讓輸入字符自動被回顯到終端的輸出上。于是,鍵盤每輸入一個字符都能在顯示器上看到它,而這些字符其實很可能是還沒被應用程序讀取到的(因為有行編輯);4、功能鍵:允許定義功能鍵。比如最常用的Ctrl+C,殺死前臺進程,就是由終端來觸發的。終端檢測到Ctrl+C輸入,會向前臺進程組發送SIGTERM信號。而誰是前臺進程組呢?這是由shell通過ioctl系統調用對終端使用TIOCSPGRP命令來設置的,每當shell啟動一個前臺進程,它都需要這么設置一下;5、輸入輸出流向控制,只有前臺進程組能夠從終端中讀數據、而不管前臺后臺程序都能向終端寫數據。這點也是必須的,跟用戶進程交互的是前臺進程,用戶的輸入當然不能被其他后臺進程搶走。但是一個進程是前臺還是后臺,是它自己是所不知道的,沒法靠進程自己來判斷什么時候可以讀終端、什么時候不能讀。所以需要終端來提供支持,如果后臺進程讀這個終端,終端的驅動程序將向其發送SIGTTIN信號,從而將其掛起。直到shell將其重新置為前臺進程時(通過fg命令),該進程才會繼續執行;6、等等;終端提供的這些功能未必都會被打開它的程序使用到,但是如果要使用,則可以通過統一的ioctl接口來設置,而不需要關心終端具體接的是什么設備,是鍵盤顯示器?還是網絡。大多數應用程序則根本不關心終端,只當它是能夠滿足讀寫需求的文件。而像shell這樣為人機交互而生的程序,則注定會跟終端打交道。對于shell來說,像“行編輯”、“回顯”這樣的功能,其實是可以不需要依賴終端的,shell程序自己可以做這樣的處理,因為要做處理的數據正是shell從終端里面讀到的數據。但是像“功能鍵”、“輸入輸出流向控制”這樣的功能,則又不得不依賴終端。比如“功能鍵”,因為這時在對終端進行讀操作的是shell啟動的前臺程序,而不是shell自己,所以不可能由shell來讀取功能鍵,然后觸發信號??梢哉f,終端是人機交互時,應用程序與用戶之間的一個中間層。如果應用程序是在跟人交互,使用終端是其不二的選擇;否則則沒有必要使用終端。這一點在sshd上面有很好的體現。當用戶使用ssh登錄到遠程機器remotehost,并執行一些操作時(比如執行cat test.txt操作),可以有兩種方式:1、ssh user:pass@remotehost,遠程登錄后,再在shell中執行cat test.txt命令;2、ssh user:pass@remotehost 'cat test.txt',直接由sshd啟動一個shell、自動執行'cat test.txt'命令;第一種方式,是登錄之后,再通過人機交互輸入命令,這時sshd會為登錄后得到的shell程序準備一個pty,以支持人機交互;而第二種方式,在登錄之后并不需要交互,所以sshd就并不會使用pty,而是直接通過socket將shell的輸入輸出跟自己連接起來(再由sshd將其轉發給ssh-client)。下面再說一下pty。pty分master和slave兩端,跟pipe的兩端很像,寫入到master端的數據可以原樣從slave端讀出,反之亦然。在上面所述的第一種方式下,各個進程的聯系如下:ssh-client <-> [socket] <-> sshd <-> [master] <-> [slave] <-> shellpty的master和slave兩端分別被sshd和shell打開,就像pipe一樣,將它們的輸入輸出連接起來。而pty跟pipe的不同之處,則正是前面所說的終端的功能(pty的slave端對于shell來說就是一個終端)。跟tty不同,tty是系統初始化時生成的,其數目是固定的(比如12個)。而pty是系統啟動后動態創建的。其創建的方法是:fd = open('/dev/ptms'),這樣就得到了一個pty。open返回的fd代表master端,通過ptyname(fd)可以得到對應slave端的文件路徑(比如'/dev/pts/2'),這個設備文件是master端被open之后動態生成的?!緳嘞蘅刂啤坑脩舻卿涷炞C成功后,getty、sshd這樣的程序就會為用戶啟動他所對應的"登錄后執行的程序",并且在此之前會通過setuid()、setgid()這樣的系統調用,設置好進程的uid和gid(用戶和組)。之后,這個進程對文件的讀、寫、執行,以及對系統調用的使用,等都會受到進程uid和gid的限制。用戶對系統的各種操作都是通過進程來完成的。而用戶的輸入輸出都被定向到他登錄后所得到的那個進程上,于是用戶能夠控制這個進程,來干他想干的事情(如果這個進程接受控制的話,比如進程運行著一個shell程序)。用戶的操作都受限于進程的uid和gid,比如文件訪問、向進程發送信號、使用系統調用、監聽網絡端口、等都需要對其做檢查。除非是root用戶,否則沒有權限使用setuid()、setgid()這樣的系統調用來修改進程的uid和gid。而login時,login、sshd這樣的進程之所以能夠設置登錄后進程的uid和gid,正是因為它們都是root用戶的進程。如果想要改變登錄用戶,則必須利用屬于root用戶的進程。一種辦法是退出登錄,然后走老路,重新跟getty、sshd這樣的進程打交道,而使用其他用戶名登錄。另一種辦法是執行一個setuid/setgid程序(參見《記一個linux內核內存提權問題》中的說明),臨時獲得root權限,再實現用戶的切換(例如su就是這樣一個能實現用戶切換的setuid命令)。為了實現進程權限控制中的各種功能,進程的uid和gid其實并不止一組,主要有如下三組:1、ruid/rgid,代表實際的用戶和組id;2、euid/egid,代表當前生效的用戶和組id;3、suid/sgid,代表保留的用戶和組id;什么意思呢?一般情況下,在用戶登錄得到的進程中,這三組id都是相同的值,與登錄用戶相對應(假設為aaa)。而用戶新創建的進程也會全部繼承這三組id。當用戶執行一個setuid/setgid程序時,執行程序的進程將得到可執行程序owner(假設為bbb)的用戶屬性,euid/egid和suid/sgid會更新為bbb(而ruid/rgid不會被更新)。這些id在進程操作別的對象時(比如寫文件、發信號、等)或被別的進程操作時(比如其他進程向其發信號、等)會被用做校驗。ruid/rgid和euid/egid在進程被操作的時候會使用到,euid/egid在進程發起操作的時候會用到。比如有一個進程,其ruid是aaa、euid是bbb,則euid為aaa或bbb的其他進程都可以向其發送信號。而該進程在進行讀寫文件、創建文件、等操作時,使用的則是用戶bbb的權限:它創建的文件owner是bbb、它在訪問owner是aaa的文件時以other權限進行校驗。那么第三組id,suid/sgid又是干什么用的呢?之前說普通用戶沒有權限使用setuid()這樣的系統調用來改變進程的uid和gid,其實這個說法并不確切。進程其實是有權限將自己的ruid/rgid、euid/egid、suid/sgid的值修改成與這三者之一相等的值。比如ruid/rgid為aaa、suid/sgid為bbb,則用戶可以任意將euid/egid設置為aaa或bbb。因為大多數情況下這三組id是等值的,所以一般說用戶進程不能修改自己的uid和gid(只能從aaa修改為aaa,相當于不能修改)。但是執行setuid的程序后,進程的這三組id就有了兩種不同的取值,ruid/rgid等于aaa、euid/egid和suid/sgid等于bbb,于是進程的uid就有了一定的選擇余地。比如此時進程的euid/egid被更新成了bbb,那就不能再以owner身份去操作aaa的文件了(注意,這個進程原本是以aaa用戶登錄而得到的)。不過沒關系,進程是有權限將euid/egid改回aaa的,因為ruid/rgid的值是aaa。但是改回來之后,ruid/rgid和euid/egid都是aaa了,要再想把euid/egid改為bbb怎么辦呢?suid/sgid就是為此而生的,作為一個備份,它的值是bbb,這使得euid/egid還能夠修改回bbb。當然,進程也有權限將euid/egid和suid/sgid都改回aaa,這將使得它們不再能修改成bbb了?!緯捦顺觥坑脩舻卿浭且粋€會話的開始。登錄之后,用戶會得到一個跟用戶使用的終端相連的進程,這個進程被稱作是這個會話的leader,會話的id就等于該進程的pid。由該進程fork出來的子進程都是這個會話的成員(進程的sid等于該會話id)。leader進程的退出,將導致它所連接的終端被hangup,這意味著會話結束。反過來,像ssh這樣的遠程連接也可以通過斷開連接的方式來使終端hangup,這將使得leader進程收到SIGHUP信號而退出。如果會話使用的是pty,其本身是隨會話的建立而創建出來的,會話結束,則pty被銷毀;而如果會話使用的是tty,其本身是在系統初始化時創建的,并不依賴于會話的建立,則會話結束時,tty依然存在。init進程檢測到使用該tty的會話已經結束,便會重新啟動一個getty來監聽該tty。不過,會話結束,并不意味著在該會話中創建的所有進程都結束了。所謂的daemon進程,正是在某個會話中創建,但是卻不依賴該會話,而常駐后臺的進程。具體來說,當終端hangup時,內核會有如下兩個動作:1、向對應會話的leader進程發送SIGHUP信號。而一般來說,會話的leader進程很可能是一個shell,它在收到SIGHUP信號后,并不是馬上退出,而是會向它所啟動的子進程都各自發送一個SIGHUP信號,將它們都殺死,然后自己才退出。不過,如果是這個作為leader進程shell自己退出,而導致終端hangup的話,向其子進程發送SIGHUP信號的事情就不會發生了,因為shell退出在先,它再也不會收到SIGHUP信號;2、修改所有打開該終端的文件句柄,改成一個不可讀不可寫的實現;所以,在會話退出之后還常駐后臺的進程肯定是沒法跟終端交互的。而要想讓進程常駐后臺,一般有如下幾種方法:1、避免shell發SIGHUP信號;主要有兩種辦法:1)主動exit,而不是直接斷開終端;2)兩次fork。因為shell只認識它自己fork出來的子進程,并不知道"子又生孫"的事情,也就不會給孫子進程發送SIGHUP信號了;2、忽略SIGHUP信號;終端hangup時進程可能收到shell發送的SIGHUP信號。信號的默認處理動作是退出進程,但是該信號是可以忽略的。忽略信號,就可以使得后臺進程不會隨會話退出而退出。nohup命令就是做這件事情的,而且它做得更完整一些,不僅忽略SIGHUP,還會將進程的標準輸入重定向為/dev/null、輸出重定向到nohup.out文件;3、使用setsid()系統調用,為進程開啟一個新的會話;從一個會話中fork出來的進程,默認都是屬于這個會話的。但是進程可以調用setsid(),使自己脫離原先的會話,而成為一個新會話的leader。于是,原先的會話退出,就不會影響到新建的會話了。setsid命令包裝了setsid()系統調用,可以為進程創建新的會話。不過它并不對新進程的輸入輸出進行重定向,這就意味著新進程的輸入輸出還是連接到原先的那個tty的,這可能跟原先的會話爭搶輸入。所以,對新會話的進程進行輸入輸出的重定向也是一件很重要的事情。一個進程成為daemon進程,可以不隨會話的退出而退出,但是進程的uid/gid并不會因此而改變。對應的用戶還可以在其他會話中,通過發信號等方式,操作那些原來由他所啟動的daemon進程(因為權限控制是以用戶為準的,而并不考慮會話)。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
成人午夜小视频| 欧美中文字幕在线视频| 国色天香2019中文字幕在线观看| 欧美丰满少妇xxxxx做受| 久久免费视频在线| 97成人精品视频在线观看| 欧美国产亚洲精品久久久8v| 亚洲精品久久久久久久久久久久久| 亚洲另类激情图| 亚洲人成77777在线观看网| 亚洲第一色在线| 亚洲 日韩 国产第一| 欧美性猛交xxxx偷拍洗澡| 在线观看国产精品淫| 北条麻妃一区二区三区中文字幕| 97在线看免费观看视频在线观看| 国产亚洲欧美一区| 久久久久久综合网天天| 日韩a**站在线观看| 8050国产精品久久久久久| 日韩视频免费大全中文字幕| 国产午夜精品美女视频明星a级| 国产一区二区三区三区在线观看| 97香蕉久久夜色精品国产| 久久视频免费在线播放| 亚洲人成电影网站色…| 亚洲欧美精品一区二区| 91中文字幕在线| 精品久久久久久中文字幕| 久久视频在线免费观看| 精品成人乱色一区二区| 国产一区二区三区在线看| 尤物99国产成人精品视频| 欧美电影免费看| 91精品国产成人www| 伊人亚洲福利一区二区三区| 久久视频免费观看| 国产精品国产三级国产aⅴ浪潮| 日韩在线一区二区三区免费视频| 91国偷自产一区二区三区的观看方式| 欧美日韩在线观看视频小说| 97婷婷涩涩精品一区| 国产91ⅴ在线精品免费观看| 亚洲一区av在线播放| 欧美壮男野外gaytube| 国产成人91久久精品| 国产精品夜间视频香蕉| 一本色道久久88综合亚洲精品ⅰ| 国产成人精品视| 日韩一区二区三区国产| 国产91精品黑色丝袜高跟鞋| 亚洲韩国青草视频| 97在线观看免费高清| 欧美一级视频免费在线观看| 57pao国产精品一区| 国产成+人+综合+亚洲欧美丁香花| 国产精品福利片| 91经典在线视频| 色阁综合伊人av| 精品女厕一区二区三区| 精品中文字幕在线| 日韩欧美一区二区三区久久| 日韩欧美亚洲综合| 久久99久久久久久久噜噜| 欧美激情中文字幕在线| 久久人人97超碰精品888| 国产小视频91| 日韩成人在线免费观看| 国产日韩专区在线| 中文字幕在线看视频国产欧美在线看完整| 亚洲精品美女在线| 久久免费精品视频| 久久久久久一区二区三区| 欧美精品成人在线| 欧美怡春院一区二区三区| 精品国产乱码久久久久酒店| 在线成人激情视频| 久久久亚洲国产天美传媒修理工| 色婷婷综合成人| 国产精品1234| 亚洲欧美国产精品久久久久久久| www.亚洲成人| 日日噜噜噜夜夜爽亚洲精品| 久久精品99无色码中文字幕| 亚洲老司机av| 国产视频精品免费播放| 成人国产在线激情| 欧美特黄级在线| 日韩最新av在线| 亚洲午夜国产成人av电影男同| 91久久久久久久久| 欧美大片在线看免费观看| 97在线视频免费看| 国内偷自视频区视频综合| 久久精品国产91精品亚洲| 久久男人的天堂| 精品久久久久久久久久久久久| 国产不卡一区二区在线播放| www.99久久热国产日韩欧美.com| 亚洲免费高清视频| 国产精品www色诱视频| 国产美女直播视频一区| 欧美大片va欧美在线播放| 91人成网站www| 欧美人与性动交a欧美精品| 亚洲欧美日韩一区二区在线| 日本精品性网站在线观看| 亚洲男人的天堂在线播放| 日韩三级成人av网| 国产精品入口尤物| 国产精品永久免费| 久久亚洲私人国产精品va| 午夜欧美不卡精品aaaaa| 法国裸体一区二区| 国内揄拍国内精品少妇国语| 精品久久久久久中文字幕大豆网| 日韩av中文字幕在线| 亚洲成人免费在线视频| 黑人精品xxx一区| 亚洲欧美第一页| 国产精品久久综合av爱欲tv| 亚洲女人天堂色在线7777| 久久亚洲精品成人| 中文字幕欧美日韩va免费视频| 亚洲成人久久久| 26uuu另类亚洲欧美日本一| 国产精品毛片a∨一区二区三区|国| 性欧美长视频免费观看不卡| 国产精品十八以下禁看| 久99久在线视频| 日韩成人免费视频| 亚洲精品色婷婷福利天堂| 韩国19禁主播vip福利视频| 精品丝袜一区二区三区| 欧美性xxxx极品高清hd直播| 永久免费精品影视网站| 色妞一区二区三区| 亚洲色图综合久久| 国外日韩电影在线观看| 日本高清不卡在线| 日韩在线中文字幕| 日韩精品极品在线观看播放免费视频| 色综合久久悠悠| 国产精品高精视频免费| 精品少妇一区二区30p| 亚洲国产精品va在线看黑人动漫| 久久精品男人天堂| 国产精品亚洲综合天堂夜夜| 在线成人免费网站| 欧美日韩激情视频| 日本精品一区二区三区在线| 国产精品偷伦免费视频观看的| 日本精品在线视频| 欧美一区二粉嫩精品国产一线天| 国产精品福利在线观看| 久久九九有精品国产23| 国产区精品在线观看| 岛国视频午夜一区免费在线观看| 91亚洲精品一区二区| 国产精品视频久| 成人精品久久av网站| 久久久久久久久国产精品| 色婷婷av一区二区三区久久| 欧美另类在线播放|