上一篇介绍了Linux的文件系统,本篇主要介绍下Linux的内核与安全。
Linux版本规则:
主、次版本为基数,说明是开发中版本;
主、次版本为偶数,说明是稳定版本。
查看命令:
uname –r
或
cat /proc/version
像我的版本是3.10.X,偶数,是稳定版本。
Linux的优缺点:
优点:
稳定、免费、安全、多任务多用户、性能要求低、适合嵌入式、开源
缺点:
没有特定厂商、软件支持度不高、命令操作(致命)
总之:爱它的人爱得死去活来,恨它的人恨的咬牙切齿
既然Linux是命令操作,那么Linux都有哪些命令呢?其实都在/usr/share/doc这个文件里,有时间多读几遍吧,虽然代价很高。。。还有就是多登陆linux多敲命令,没别的好办法了。
内核:
管理计算机硬件的是操作系统的核心Kernel,这个核心是需要被保护的,所以我们使用者只能透过shell来跟核心互动以让计算机完成我们想要完成的工作。
Shell中我们最常用的是Bash(Bourne AgainShell的简称)
当操作员登陆上来操作的时候,内存中会记录操作员本次操作的命令,当登出时这部分记忆会自动记录到~/.bash_history磁盘中。这种机制给我们带来了便捷,也跟我们带来了安全隐患。
便捷1:本次操作时可以通过上下键去内存检索前面执行过的命令,对一些很长的命令我们一旦敲错了个别参数没有执行成功,很方便就可以修正。还可以回放,例如命令!!就是回放最新的一条命令。
便捷2:如果这次做了什么不该做的操作,下次登陆上来想要修正但是又忘记前面搞了什么事情,可以通过history来帮助回忆。
隐患:一旦黑客入侵了我们系统,可以通过history发现很多敏感的信息。
注意1:在linux中敲命令时不要把敏感信息特别是密码直接以命令的方式执行,一定要用弹出passwd提示框然后输入密码的方式(包括自己在写shell脚本时也要这么去设计),这样就算黑客入侵了电脑,也看不到我们的密码。
注意2:由于linux这种内存机制,我们在做关机或者修改变量等操作时记得手动执行下sync这个命令,我自己也经常忽视,将内存中的信息写入磁盘,防止丢失。
我们还可以给命令取别名,或者你可以理解为英文里的for short
例如:alias lm='ls -all',以后只要执行lm就是ls –all了。
取消用unalias
bash双引号和单引号的区别,看一个例子你就能秒懂:
双引号内会自动做变量的转换,而单引号内就是强制字符串的意思。
子进程只会继承父进程的环境变量,不会继承父进程的自定义变量,所以要把设置的变量export一下才可以同步到env中。
想找一个PATH内预设命令的具体目录需要用which命令
获取当前进程号:echo $$
获取上一条命令运行结果:echo $? ,返回0是成功,其它是失败
我自己在玩Hadoop的时候经常遇到某种错误XXXXlimited,原来linux为了防止多用户同时消耗某种资源而设置的限制。
可以看得到做了哪些限制吧:进程数、文件数量、内存、等等
可以通过ulimit命令对限制进行修改,但是记住需要与source命令配合,将刚刚设置的内容读取到当前环境中。
输入输出:
标准输入(stdin):代码为0,使用<或者<<
标准输出(stdout):代码为1,使用>或者>>
错误输出(stderr):代码为2,使用2>或者2>>
单个>是以覆盖方式更新,双>是以累加方式更新。
/dev/null是linux的黑洞,任何丢入其中的都石沉大海了。
正则表达式在linux的grep里是用[]来修饰的
1 反向,不想要啥,[^],例如A[^b]标识的就是包含A但是后面不跟着b。
2 连续,x-y标识一端连续的输入,例如[a-z]标识的就是小写英文字母
3 行首^和行尾$,记得与反向区别是没有中括号。^[0-9]这个意思是必须数字开头
4 .小数点代表任意的一个字符
5 *星号代表前面的字符出现0到N次,a*就标识空白、aa、aaa、。。。。
6 与*相对应的是限定符{n},a{2}标识的是aa,一定出现2次。由于{}是shell脚本的敏感字符,使用时需要反斜杠转义。a{2,5}标识的是范围,aa、aaa、aaaa、aaaaa
7 很发杂的逻辑,如果一个表达式写不出来的,也可以通过管道来拆分成多个grep。
printf命令,控制打印格式,操作linux时确实没有什么大用,不过写shell脚本时如果想按格式输出一些数据printf还是很给力的。
文本对比命令diff也很实用,diff file1 file2,更牛掰的是diff还可以比对两个目录哦。
awk –F ‘分隔符’ {shell命令}{filename}
对filenames里每一行,先经过_F拆分,然后执行action这个shell命令
BEGIN块和END块,需要掌握。
统计某文件行数:
统计目录文件大小的和:
Shell Script:
Shell Script的总原则:
1 不要将CPU密集型的工作丢给Linux去干,shell脚本不擅长干这个。
2 开头第一行必须跟内核的类型:#!/bin/bash
3 结尾以exit 0或其它返回值告知调用方脚本执行结果状态。
4 做过高级语言开发的小伙伴们注意了,这鸟脚本不能随便空格,以下是错误的。
PS:上图中还有个错误,date要用圆括号,而不是花括号。
一般的脚本我们直接./shellFile或者sh shellFile方式来执行,相当于重新开启了一个进程,里面设置的环境变量等执行结束后并不会影响主进程。
如果要保留脚本中的设置,需要用source shellFile的方式来执行脚本。
test命令,很不错,写shell时做判断非常好用。
与test类似的语法是中括号封闭起来,不过可读性不test,而且[]里的组件要用空格来分开,还需要用双括号引起来。
Shell script的调试:
Shell脚本执行有可选的参数,可以方便我们进行脚本的调试。
Sh [-nvx] my-srcipt.sh
-n : 不执行script,只检查语法,很有意义。
-v : 意义不大,将脚本本身输出到屏幕。
-x : 将脚本详细的执行过程打印到屏幕,很有意义。
安全:
上一篇只是介绍了文件系统的权限设置,而linux是个多用户共享平台,所以我们还需要认证掌握linux自己的权限设计。
虽然我们一直在用用户名和组名去操作和限制登陆用户,其实UID和GID才是用户身份真正的象征。
UID:用户的ID,0是系统管理员root的账号,不可被占用,剩下的理论上随便设置,一般系统都会默认给出添加规则,像我用的centos7默认普通用户是1000开始。
GID:组群的ID,0也是给系统管理员组root用的,不可被侵犯。
还需要记住
/etc/passwd:记录了所有账号与使用者,包括root的相关信息,虽然名字有个passwd但是不能被它骗了,里面其实没有密码内容。
/etc/shadow:这个里面才是保存的密文的密码:
/etc/group:所有组名
一次登陆的过程是先通过/etc/passwd先找到这个用户,获取到UID;再去/etc/group去找对应的组,获取到GID;再去/etc/shadow里找到密码与用户输入的比对;全部通过后就会加载用户的执行环境准备接收用户命令了。
PS1:以前玩linux一直认为一个用户只能属于一个group,但是现在明白我错了,一个用户可以属于多个group。你可能会说不可能,因为文件系统里一个文件或者一个目录明明只能属于一个用户和组。对的,关键在于“切换”这个概念。一个用户虽然可以属于多个group,但是当前时间只能赋予一个group的权限,可以通过newgrp这个命令进行group切换。
PS2:如果一个用户不用了,可以通过修改/etc/shadow的方式让它失效,除非一定要干掉这个用户,否则尽量不要使用userdel这个命令。
su和sudo命令:
这俩命令的出发点都是一样的,由于linux是多用户公用的,往往某个用户在操作的时候需要使用到其他用户的权限(大部分是root权限),为了满足这种场景所以提供了su和sudo命令赋予该用户更多的权限。
这俩命令在使用的时候最大的区别是su切换需要输入对方的密码,而sudo切换只需要切换自己的密码。其实这俩命令的前世今生与应用场景才是我们需要真正掌握的。
为了方面解释,下面都以普通用户切换root权限为案例介绍。
先看su命令:
su命令最大的缺陷是需要把root密码告诉所有想使用root权限的人,这就会造成root密码的暴漏,越多的人知道越不安全。优点是方便,普通用户直接可以切换到root用户,切换后的操作不受限制。
PS:su和su –命令也是有区别的,su –才是完整的切换root,包括path和自动home跳转;而su将会保留当前目录,不加载path。
再看sudo命令:
为了解决su命令暴露root密码的问题,我们用默认某些普通用户可以随意切换root用户的权限,但是为了防止是授权用户本人在操作,所以切换前需要输入自己的密码,这套逻辑就是sudo。只有被root用户写入/etc/sudoers中的用户才可以用sudo切换,否则会报错:
对于/etc/sudoers的编写:
内容如下:
这个文件是只读的,虽然通过修改权限可破解,但是由于是系统内部文件,自己vi不好容易让系统出问题,所以需要用命令来修改。
命令是visudo
PS:其实这个命令挺搞笑的,就是打来了个vi工具来改/etc/sudoers文件而已,应该在最终保存时增加了格式和安全校验吧。默认的是用户名,可以前面添加%代表的是组名。例如%groupA代表的就是所有属于groupA下面的组,都可以sudo到root来。
除开用户名,其它参数还有挺有用的,也罗列下吧:
看到这可能有人要打我脸了,su命令方式容易丢root密码,那么sudo方式普通用户密码丢失了不也相当于root丢失了么?sudo考虑到这一点,为了不让普通用户为所欲为,要对他们进行限制,例如root的密码不允许普通用户修改吧,否则太恐怖了。
OK,介绍完了,你可能又会问既然sudo这么好,没啥缺点么?有,而且也比较致命,sudu只能执行一道shell命令!但是我个人不认为这是个缺陷,因为我们对权限切换的理解是某个别的命令权限不够临时切换下,如果要长期使用执行多条命令,那你就要有root的密码才可以(su或者联系root帮忙操作)。
PS:其实也有方案解决,既不想暴露root密码给别人,又让别人用sudo来执行多条命令,方案如下:
然后这些受信任用户直接sudo su – ,然后输入自己的密码,就可以切换成root用户了!
但我个人还是不推荐,就是上面的原因,我们要透过命令去深挖设计者的初衷。
OK,sudo、su搞久了以后操作员会人格分裂,我是谁?我在哪?我在干啥?
可以通过观察控制台,控制台#开头,说明当前是root用户;$开头说明当前是一般用户。
还可以查看文件/var/log/secure, /var/log/messages
这俩文件里存放着用户登陆和切换的日志内容,方便回忆。
Linux其它常用的登入操作文档:
/var/log/cron:crontab编排如果没有执行成功,来这里面找。
/var/log/dmesg: 开机检测的日志
/var/log/lastlog:linux系统里所有用户最后登录时间
/var/log/messages:这个信息最重要,系统发生错误优先来这里面找
/var/log/secure:sudo su ssh telnet等涉及到用户密码的操作,都记录这里。
/var/log/faillog:尝试登陆系统但是失败的信息,通过这个观察有没有被攻击。