Windows和Linux组织文件区别

Windows: 以多根的方式组织文件 C:\ D:\ E:\
Linux: 以单根的方式组织文件 /
目录结构FSH(Filesystem Hierarchy Standard)
| 路径 | 用处 |
|---|---|
| bin | 普通用户使用的命令/bin/ls , /bin/date RHEL7淘汰 |
| sbin | 管理员使用的命令/sbin/service RHEL7淘汰 |
| dev | 设备文件/dev/sda , /dev/tty1 , /dev/pts/1 , /dev/zero , /dev/null , /dev/random |
| root | root用户的HOME |
| home | 存储普通用户家目录 |
| proc | 虚拟的文件系统,反应出来的是内核,进程信息或实时状态 |
| usr | 系统文件,相当于C:\Windows/usr/local 软件安装的目录,相当于C:\Program/usr/bin 普通用户使用的应用程序/usr/sbin 管理员使用的应用程序/usr/lib 库文件Glibc/usr/lib64 库文件Glibc |
| boot | 存放系统启动相关的文件,例如kernel,grub(引导转载程序) |
| etc | 配置文件 |
| lib | 库文件Glibc RHEL7淘汰 |
| lib64 | 库文件Glibc RHEL7淘汰 |
| tmp | 临时文件(全局可写,进程产生的临时文件) |
| var | 存档的是一些变化文件,比如数据库,日志,邮件..... |
| media | 移动设备默认的挂载点 |
| mnt | 手工挂载设备的挂载点 |
| net | automount进程挂载 |
文件定位路径
路径的作用:定位文件 你要在哪儿创建文件? 你要将什么文件复制到什么地方? 你要删除什么地方的什么文件?

绝对路径:从/开始的路径 /home/aaron/file1
相对路径:从当前路径开始 a.txt ./a.txt ../a.txt
[root@xwz /]# useradd aaron
[root@xwz /]# touch /home/aaron/file1 # 绝对路径
[root@xwz /]# touch ~/file2
[root@xwz /]# touch ~aaron/file3
[root@xwz 123]# pwd
[root@xwz 123]# mkdir abc # 相对路径
[root@xwz 123]# touch ../file3
[root@xwz 123]# touch file4
[root@xwz 123]# touch abc/file5
[root@xwz 123]# cd /home/aaron/ # 绝对路径
[root@xwz aaron]# cd ~aaron/
[root@xwz aaron]# cd ../../root # 相对路径
[root@xwz ~]# cd - # 返回上次目录
/home/aaron
[root@xwz aaron]# cd ~ # 直接回家
文件管理命令
几个常见的处理目录的命令
- ls(英文全拼:list files): 列出目录及文件名
- cd(英文全拼:change directory):切换目录
- pwd(英文全拼:print work directory):显示目前的目录
- mkdir(英文全拼:make directory):创建一个新的目录
- rmdir(英文全拼:remove directory):删除一个空的目录
- cp(英文全拼:copy file): 复制文件或目录
- rm(英文全拼:remove): 删除文件或目录
- mv(英文全拼:move file): 移动文件与目录,或修改文件与目录的名称
touch(创建新文件)
用于修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的文件。
touch 文件名
实例
- 创建新空白文件
[root@localhost ~]# touch newfile
- 修改文件时间
touch -t 10111312 newfile
# 10月11号13时12
mkdir (创建新目录)
创建新的目录的
mkdir [-mpv] 目录名称
选项
- -m:配置文件的权限喔!直接配置,不需要看默认权限 (umask)
- -p:帮助你直接将所需要的目录(包含上一级目录)递归创建起来!
- -v:显示目录创建的过程
实例
[root@localhost ~]# mkdir dir
# 创建一个新的文件夹叫dir
[root@localhost ~]# mkdir a/b/c
mkdir: 无法创建目录"a/b/c": 没有那个文件或目录
# 无法直接创建多层目录
[root@localhost ~]# mkdir -p a/b/c
# 加上-p选项之后可以自动创建父级目录
[root@localhost ~]# mkdir -pv dir1/dir2
mkdir: 已创建目录 "dir1"
mkdir: 已创建目录 "dir1/dir2"
# 显示详细的创建过程
cp (复制文件或目录)
拷贝文件和目录
cp [选项]... 源文件... 目录
选项
- -a:相当於 -pdr 的意思,至於 pdr 请参考下列说明;(常用)
- -d:若来源档为连结档的属性(link file),则复制连结档属性而非文件本身;
- -f:为强制(force)的意思,若目标文件已经存在且无法开启,则移除后再尝试一次;
- -i:若目标档(destination)已经存在时,在覆盖时会先询问动作的进行(常用)
- -l:进行硬式连结(hard link)的连结档创建,而非复制文件本身;
- -p:连同文件的属性一起复制过去,而非使用默认属性(备份常用);
- -r:递归持续复制,用於目录的复制行为;(常用)
- -s:复制成为符号连结档 (symbolic link),亦即『捷径』文件;
- -u:若 destination 比 source 旧才升级 destination !
- -v:显示复制的详细过程
实例
[root@localhost ~]# mkdir /home/dir{1,2}
[root@localhost ~]# touch install.log
[root@localhost ~]# cp -v install.log /home/dir1
# 复制文件到目录下
[root@localhost ~]# cp -v install.log /home/dir1/abc.txt
# 复制文件到目录下,并且重命名为abc.txt
[root@localhost ~]# cp -rv /etc /home/dir1
# 复制目录
[root@localhost ~]# cp -rv /etc/sysconfig/network-scripts/ifcfg-ens33 /etc/passwd /etc/hostname /home/dir2
# 将多个文件复制到同一个目录
[root@localhost ~]# cp -rv /etc/sysconfig/network-scripts/ifcfg-ens33 /etc/passwd /etc/hostname .
# 将多个文件复制到当前目录
[root@localhost ~]# type -a cp
cp 是 `cp -i' 的别名
cp 是 /usr/bin/cp
[root@localhost ~]# cp -rv /etc/sysconfig/network-scripts/ifcfg-ens33 /etc/sysconfig/network-scripts/ifcfg-ens33.bak
[root@localhost ~]# cp -rv /etc/sysconfig/network-scripts/{ifcfg-ens33,ifcfg-ens33.bak}
[root@localhost ~]# cp -rv /etc/sysconfig/network-scripts/ifcfg-ens33{,-old}
# 备份配置文件
mv(移动文件与目录,或修改名称)
移动文件与目录,或修改名称
mv [选项]... 源文件... 目录
选项
- -f:force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖;
- -i:若目标文件 (destination) 已经存在时,就会询问是否覆盖!
- -u:若目标文件已经存在,且 source 比较新,才会升级 (update)
- -v:显示复制的详细过程
实例
[root@localhost ~]# mv file1 /home/dir3
# 将file1移动到/home/dir3
[root@localhost ~]# mv file2 /home/dir3/file20
# 将file2移动到/home/dir3,并且改名file20
[root@localhost ~]# mv file4 file5
# 将file4改名为file5
rm (移除文件或目录)
移除文件或目录
rm [选项]... 文件...
选项
- -f:就是 force 的意思,忽略不存在的文件,不会出现警告信息;
- -i:互动模式,在删除前会询问使用者是否动作
- -r:递归删除啊!最常用在目录的删除了!这是非常危险的选项!!!
实例
[root@localhost ~]# cd /home
[root@localhost home]# rm -rf dir1
文本文件查看
在Linux中一切皆文件,说的就是Linux利用文本文件来保存系统所有的设置。
我们在Linux中想实现一个功能,不可避免的需要查看文本文件,修改文本文件。
cat
用于打开文本文件并显示出来
cat [选项]... [文件]...
选项
- -n:由 1 开始对所有输出的行数编号
- -b:和 -n 相似,只不过对于空白行不编号。
- -s:当遇到有连续两行以上的空白行,就代换为一行的空白行。
- -A:显示控制字符。
实例
- 查看anaconda-ks.cfg文件
[root@localhost ~]# cat anaconda-ks.cfg
- 查看anaconda-ks.cfg文件,并且显示行号
[root@localhost ~]# cat -n anaconda-ks.cfg
less
可以随意浏览文件,支持翻页和搜索,支持向上翻页和向下翻页
实例
[root@localhost ~]# less anaconda-ks.cfg
head
查看文件的开头部分的内容
head [选项]... [文件]...
参数
- -q:隐藏文件名,默认是隐藏
- -v:显示文件名
- -c<数目>:显示的字节数。
- -n<行数>:显示的行数。
实例
- 查看文件的前6行
[root@localhost ~]# head -n 6 anaconda-ks.cfg
tail
会把文本文件里的最尾部的内容显示在屏幕上
tail [选项]... [文件]...
参数
- -f:循环读取
- -q:隐藏文件名,默认隐藏
- -v:显示文件名
- -c<数目>:显示的字节数
- -n<行数>:显示文件的尾部 n 行内容
- -s:与-f合用,表示在每次反复的间隔休眠S秒
实例
- 查看文件anaconda-ks.cfg尾部的3行
[root@localhost ~]# tail -n 3 anaconda-ks.cfg
- 查看日志的实时更新情况
[root@localhost ~]# tail -f /var/log/messages
# ctrl+c退出
- 查看文件anaconda-ks.cfg从第10行到结尾
[root@localhost ~]# tail -n +10 anaconda-ks.cfg
grep
针对文件内容进行过滤,本工具属于文本三剑客,后续会详细讲解,目前只要求初学者掌握最基本的实例即可
实例
[root@xwz ~]# grep 'root' /etc/passwd
# 在/etc/passwd的文件中找出有root的行
[root@xwz ~]# grep '^root' /etc/passwd
# 在/etc/passwd中找出root开头的行
[root@xwz ~]# grep 'bash$' /etc/passwd
# 在/etc/passwd中找出bash结尾的行
文本文件编辑
在Linux中只掌握文本查看是远远不够的,我们还需要掌握编辑文本文件。
Linux上也有图形化的文本编辑器,类似于windows的记事本,但是很多时候我们只能用命令行来管理Linux操作系统,所以必须要掌握命令行的文本编辑器软件。
目前常见的命令行文本编辑器
- nano:在debain系列的系统上会比较常见,但是其他的Linux发行版也都可以安装
- vi:所有的 Unix Like 系统都会内建 vi 文本编辑器,其他的文本编辑器则不一定会存在。
- vim:具有程序编辑的能力,可以主动的以字体颜色辨别语法的正确性,方便程序设计。
目前vim是使用的最多的,也是比较推荐的,下面就来讲一下vim
什么是 vim?
Vim是从 vi 发展出来的一个文本编辑器。代码补完、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。
简单的来说, vi 是老式的字处理器,不过功能已经很齐全了,但是还是有可以进步的地方。 vim 则可以说是程序开发者的一项很好用的工具。
连 vim 的官方网站 (http://www.vim.org) 自己也说 vim 是一个程序开发工具而不是文字处理软件。
vim是一个纯命令行文本编辑器,很多文本编辑的功能都是通过键盘快捷键的方式完成,所以我们需要记住常用的键位,在vim官方网站上我们可以找到vim键盘图的完整版,不过对于初学者来说,我们只需要知道常用的就可以了。
![]()
vi/vim 的使用
基本上 vi/vim 共分为三种模式,分别是命令模式(Command mode),输入模式(Insert mode)和末行模式(Last line mode)。 这三种模式的作用分别是:
命令模式
用户刚刚启动 vi/vim,便进入了命令模式。
此状态下敲击键盘动作会被Vim识别为命令,而非输入字符。比如我们此时按下i,并不会输入一个字符,i被当作了一个命令。
以下是常用的几个命令:
- i切换到输入模式,以输入字符。
- x删除当前光标所在处的字符。
- :切换到末行模式,以在最底一行输入命令。
若想要编辑文本:启动Vim,进入了命令模式,按下i,切换到输入模式。
命令模式只有一些最基本的命令,因此仍要依靠末行模式输入更多命令。
输入模式
在命令模式下按下i就进入了输入模式。
在输入模式中,可以使用以下按键:
- 字符按键以及Shift组合,输入字符
- ENTER,回车键,换行
- BACK SPACE,退格键,删除光标前一个字符
- DEL,删除键,删除光标后一个字符
- 方向键,在文本中移动光标
- HOME/END,移动光标到行首/行尾
- Page Up/Page Down,上/下翻页
- Insert,切换光标为输入/替换模式,光标将变成竖线/下划线
- ESC,退出输入模式,切换到命令模式
末行模式
在命令模式下按下:(英文冒号)就进入了末行模式。
末行模式可以输入单个或多个字符的命令,可用的命令非常多。
在末行模式中,基本的命令有:
- :q退出程序
- :w保存文件
按ESC键可随时退出末行模式。
简单的说,我们可以将这三个模式的关系用下图来表示:
![]()
vi/vim使用实例
有些linux发行套件上并没有安装vim,我们可以安装一下,kali 上默认是安装好的
┌──(root㉿kali)-[~]
└─# apt-get install vim
vi和vim大部分的操作完全一模一样,所以会使用vim自然也会使用vi
编辑一个文档
直接输入vim 文件名就能够进入 vim 的一般模式了。请注意,记得 vim 后面一定要加文件名,不管该文件存在与否!
┌──(root㉿kali)-[~]
└─# vim file.txt
输入这条命令之后,会看到如下画面
![]()
按下i进入输入模式(也称为编辑模式),开始编辑文字
在命令模式之中,只要按下i,o,a等字符就可以进入输入模式了!
在编辑模式当中,你可以发现在左下角状态栏中会出现--INSERT--的字样,那就是可以输入任意字符的提示。
这个时候,键盘上除了 Esc 这个按键之外,其他的按键都可以视作为一般的输入按钮了,所以你可以进行任何的编辑。
![]()
好了,假设我已经按照上面的样式给他编辑完毕了,那么应该要如何退出呢?是的!没错!就是给他按下 Esc 这个按钮即可!马上你就会发现画面左下角--INSERT--的不见了!
![]()
输入:wq后回车即可保存离开,注意其中的冒号必须是英文输入法下的冒号!
![]()
现在我们就成功创建了一个文件,查看文件的内容吧
[root@localhost ~]# ls -lh file.txt
[root@localhost ~]# cat file.txt
vi/vim按键说明
除了上面简易范例的 i, Esc, :wq 之外,其实 vim 还有非常多的按键可以使用。
下面将会列举出vim非常多的常用按键,初学者只需要浏览一遍,记住大概vim有哪些功能,等后面大量使用vim的时候,再来翻阅笔记,并且在多次使用中把这些功能记住。
命令模式
下面的操作都是在命令模式下进行的
移动光标的方法
| h 或 向左箭头键(←) | 光标向左移动一个字符 |
|---|---|
| j 或 向下箭头键(↓) | 光标向下移动一个字符 |
| k 或 向上箭头键(↑) | 光标向上移动一个字符 |
| l 或 向右箭头键(→) | 光标向右移动一个字符 |
| [Ctrl] + [f] | 屏幕『向下』移动一页,相当于 [Page Down]按键 (常用) |
| [Ctrl] + [b] | 屏幕『向上』移动一页,相当于 [Page Up] 按键 (常用) |
| [Ctrl] + [d] | 屏幕『向下』移动半页 |
| [Ctrl] + [u] | 屏幕『向上』移动半页 |
| + | 光标移动到非空格符的下一行 |
| - | 光标移动到非空格符的上一行 |
| n |
那个 n 表示『数字』,例如 20 。按下数字后再按空格键,光标会向右移动这一行的 n 个字符。例如 20 |
| 0 或功能键[Home] | 这是数字『 0 』:移动到这一行的最前面字符处 (常用) |
| $ 或功能键[End] | 移动到这一行的最后面字符处(常用) |
| H | 光标移动到这个屏幕的最上方那一行的第一个字符 |
| M | 光标移动到这个屏幕的中央那一行的第一个字符 |
| L | 光标移动到这个屏幕的最下方那一行的第一个字符 |
| G | 移动到这个档案的最后一行(常用) |
| nG | n 为数字。移动到这个档案的第 n 行。例如 20G 则会移动到这个档案的第 20 行(可配合 :set nu) |
| gg | 移动到这个档案的第一行,相当于 1G 啊! (常用) |
| n |
n 为数字。光标向下移动 n 行(常用) |
文本的搜索与替换
| /word | 向光标之下寻找一个名称为 word 的字符串。 (常用) |
|---|---|
| ?word | 向光标之上寻找一个字符串名称为 word 的字符串。 |
| n | 这个 n 是英文按键。代表重复前一个搜寻的动作。 |
| N | 这个 N 是英文按键。与 n 刚好相反,为『反向』进行前一个搜寻动作。 |
| :n1,n2s/word1/word2/g | n1 与 n2 为数字。在第 n1 与 n2 行之间寻找 word1 这个字符串,并将该字符串取代为 word2 (常用) |
| :1,$s/word1/word2/g 或 :%s/word1/word2/g | 从第一行到最后一行寻找 word1 字符串,并将该字符串取代为 word2 !(常用) |
| :1,$s/word1/word2/gc 或 :%s/word1/word2/gc | 从第一行到最后一行寻找 word1 字符串,并将该字符串取代为 word2 !且在取代前显示提示字符给用户确认 (confirm) 是否需要取代!(常用) |
删除/剪切、复制与粘贴
| x, X | 在一行字当中,x 为向后删除一个字符 (相当于 [del] 按键), X 为向前删除一个字符(相当于 [backspace] 亦即是退格键) (常用) |
|---|---|
| nx | n 为数字,连续向后删除 n 个字符。举例来说,我要连续删除 10 个字符, 『10x』。 |
| dd | 删除/剪切光标所在的那一整行(常用) |
| ndd | n 为数字。删除/剪切光标所在的向下 n 行,例如 20dd 则是删除 20 行 (常用) |
| d1G | 删除光标所在到第一行的所有数据 |
| dG | 删除光标所在到最后一行的所有数据 |
| d$ | 删除游标所在处,到该行的最后一个字符 |
| d0 | 那个是数字的 0 ,删除光标所在处,到该行的最前面一个字符 |
| yy | 复制游标所在的那一行(常用) |
| nyy | n 为数字。复制光标所在的向下 n 行,例如 20yy 则是复制 20 行(常用) |
| y1G | 复制游标所在行到第一行的所有数据 |
| yG | 复制游标所在行到最后一行的所有数据 |
| y0 | 复制光标所在的那个字符到该行行首的所有数据 |
| y$ | 复制光标所在的那个字符到该行行尾的所有数据 |
| p, P | p 为将已复制的数据在光标下一行贴上,P 则为贴在光标上一行! 举例来说,我目前光标在第 20 行,且已经复制了 10 行数据。则按下 p 后, 那 10 行数据会贴在原本的 20 行之后,亦即由 21 行开始贴。但如果是按下 P 呢? 那么原本的第 20 行会被推到变成 30 行。 (常用) |
| J | 将光标所在行与下一行的数据结合成同一行 |
| c | 重复删除多个数据,例如向下删除 10 行,[ 10c ] |
| u | 复原前一个动作。(常用) |
| [Ctrl]+r | 重做上一个动作。(常用) |
| . | 重复前一个动作。 如果你想要重复删除、重复贴上等等动作,按下小数点『.』就好了! (常用) |
进入输入或取代的编辑模式
| i, I | 进入输入模式(Insert mode): i 为『从目前光标所在处输入』, I 为『在目前所在行的第一个非空格符处开始输入』。 (常用) |
|---|---|
| a, A | 进入输入模式(Insert mode): a 为『从目前光标所在的下一个字符处开始输入』, A 为『从光标所在行的最后一个字符处开始输入』。(常用) |
| o, O | 进入输入模式(Insert mode): 这是英文字母 o 的大小写。o 为在目前光标所在的下一行处输入新的一行; O 为在目前光标所在的上一行处输入新的一行!(常用) |
| r, R | 进入取代模式(Replace mode): r 只会取代光标所在的那一个字符一次;R会一直取代光标所在的文字,直到按下 ESC 为止;(常用) |
| [Esc] | 退出编辑模式,回到一般模式中(常用) |
末行模式下的储存、离开等指令
| :w | 将编辑的数据写入硬盘中(常用) |
|---|---|
| :w! | 若文件属性为『只读』时,强制写入该文件。不过,到底能不能写入, 还是跟你对该文件的权限有关 |
| :q | 离开 vi (常用) |
| :q! | 若曾修改过文件,又不想储存,使用 ! 为强制离开不储存。 |
| :wq | 储存后离开,若为 :wq! 则为强制储存后离开 (常用) |
| ZZ | 这是大写的 Z 喔!如果修改过,保存当前文件,然后退出!效果等同于(保存并退出) |
| :x | 效果等同于(保存并退出) |
| :X | 大写的X,用于加密文件 |
| ZQ | 不保存,强制退出。效果等同于:q!。 |
| :w [filename] | 将编辑的数据储存成另一个文件(类似文件另存为) |
| :r [filename] | 在编辑的数据中,读入另一个文件的数据。亦即将 『filename』 这个文件内容加到光标所在行后面 |
| :n1,n2 w [filename] | 将 n1 到 n2 的内容储存成 filename 这个文件。 |
| :! command | 暂时离开 vi 到bash命令行下执行 command 的显示结果!例如 『:! ls /home』即可在 vi 当中察看 /home 底下以 ls 输出的文件信息! |
vim环境变量修改
| :set nu | 显示行号,设定之后,会在每一行的前缀显示该行的行号 |
|---|---|
| :set nonu | 与 set nu 相反,为取消行号! |
配置网络服务
配置网络参数
使用nmtui命令来配置网络
[root@localhost ~]# nmtui






图形化
没有灵魂的图形化修改方式


双击 wired connection1


命令行
┌──(root㉿kali)-[~]
└─# vim /etc/network/interfaces
auto eth0
iface eth0 inet static
address 192.168.173.11
netmask 255.255.255.0
gateway 192.168.173.2
┌──(root㉿kali)-[~]
└─# cat /etc/resolv.conf
nameserver 114.114.114.114
#设置 DNS 服务器
最后需要重启网络服务并测试网络是否联通
┌──(root㉿kali)-[~]
└─# systemctl restart networking.service
远程控制服务
配置sshd服务
sshd是基于SSH协议开发的一款远程管理服务程序,不仅使用起来方便快捷,而且能够提供两种安全验证的方法:
- 基于口令的验证—用账户和密码来验证登录;
- 基于密钥的验证—需要在本地生成密钥对,然后把密钥对中的公钥上传至服务器,并与服务器中的公钥进行比较;该方式相较来说更安全。
sshd服务的配置信息保存在/etc/ssh/sshd_config文件中。运维人员一般会把保存着最主要配置信息的文件称为主配置文件,而配置文件中有许多以井号开头的注释行,要想让这些配置参数生效,需要在修改参数后再去掉前面的井号。 sshd服务配置文件中包含的参数以及作用
| 参数 | 作用 |
|---|---|
| Port 22 | 默认的sshd服务端口 |
| ListenAddress 0.0.0.0 | 设定sshd服务器监听的IP地址 |
| Protocol 2 | SSH协议的版本号 |
| HostKey /etc/ssh/ssh_host_key | SSH协议版本为1时,DES私钥存放的位置 |
| HostKey /etc/ssh/ssh_host_rsa_key | SSH协议版本为2时,RSA私钥存放的位置 |
| HostKey /etc/ssh/ssh_host_dsa_key | SSH协议版本为2时,DSA私钥存放的位置 |
| PermitRootLogin yes | 设定是否允许root管理员直接登录 |
| StrictModes yes | 当远程用户的私钥改变时直接拒绝连接 |
| MaxAuthTries 6 | 最大密码尝试次数 |
| MaxSessions 10 | 最大终端数 |
| PasswordAuthentication yes | 是否允许密码验证 |
| PermitEmptyPasswords no | 是否允许空密码登录(很不安全) |
开启ssh远程登陆
┌──(root㉿kali)-[~]
└─# systemctl start ssh
┌──(root㉿kali)-[~]
└─# systemctl enable ssh
┌──(root㉿kali)-[~]
└─# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
┌──(root㉿kali)-[~]
└─# vim /etc/ssh/sshd_config
PermitRootLogin yes
┌──(root㉿kali)-[~]
└─# passwd
New password: kali
Retype new password: kali
passwd: password updated successfully
┌──(root㉿kali)-[~]
└─# systemctl restart ssh

配置免密登陆
对称加密算法
- 使用同一把密钥(即对称密钥)进行加密和解密,加密速度快,适用于大量数据加密,常用的对称加密算法包括DES、3DES、AES等。
非对称加密算法
- 非对称加密(Asymmetric Encryption):使用公钥进行加密,私钥进行解密的加密方式,加密速度相对慢,但公钥可以公开发布,可以方便地进行密钥交换,常用的非对称加密算法包括RSA、DSA等。
- 数据加密
- 数字签名*
生成证书



┌──(root㉿kali)-[~]
└─# vim .ssh/authorized_keys
# 把public key贴到这里


取消密码登陆
┌──(root㉿kali)-[~]
└─# vim /etc/ssh/sshd_config
PasswordAuthentication no
┌──(root㉿kali)-[~]
└─# systemctl restart ssh
iptables相关概念
防火墙除了软件及硬件的分类,也可对数据封包的取得方式来分类,可分为代理服务器(Proxy)及封包过滤机制(IP Filter)。
- 代理服务
- 是一种网络服务,通常就架设在路由上面,可完整的掌控局域网的对外连接。
- IP Filter
- 这种方式可以直接分析最底层的封包表头数据来进行过滤,所以包括 MAC地址, IP, TCP, UDP, ICMP 等封包的信息都可以进行过滤分析的功能,用途非常广泛。
其实Iptables服务不是真正的防火墙,只是用来定义防火墙规则功能的"防火墙管理工具",将定义好的规则交由内核中的netfilter即网络过滤器来读取,从而真正实现防火墙功能。 iptables抵挡封包的方式:
- 拒绝让 Internet 的封包进入 Linux 主机的某些 port
- 拒绝让某些来源 IP 的封包进入
- 拒绝让带有某些特殊标志( flag )的封包进入
- 分析硬件地址(MAC)来提供服务
五链
iptables命令中设置数据过滤或处理数据包的策略叫做规则,将多个规则合成一个链,叫规则链。规则链则依据处理数据包的位置不同分类:
- PREROUTING
- 在进行路由判断之前所要进行的规则(DNAT/REDIRECT)
- INPUT
- 处理入站的数据包
- OUTPUT
- 处理出站的数据包
- FORWARD
- 处理转发的数据包
- POSTROUTING
- 在进行路由判断之后所要进行的规则(SNAT/MASQUERADE)
四表
iptables中的规则表是用于容纳规则链,规则表默认是允许状态的,那么规则链就是设置被禁止的规则,而反之如果规则表是禁止状态的,那么规则链就是设置被允许的规则。
- raw表
- 确定是否对该数据包进行状态跟踪
- mangle
/ˈmæŋɡl/表- 为数据包设置标记(较少使用)
- nat表
- 修改数据包中的源、目标IP地址或端口
- filter表
- 确定是否放行该数据包(过滤)

规则表的先后顺序:raw→mangle→nat→filter 规则链的先后顺序:
- 入站顺序
- PREROUTING→INPUT
- 出站顺序
- OUTPUT→POSTROUTING
- 转发顺序
- PREROUTING→FORWARD→POSTROUTING
iptables命令中则常见的控制类型有:
- ACCEPT
- 允许通过
- LOG
- 记录日志信息,然后传给下一条规则继续匹配
- REJECT
- 拒绝通过,必要时会给出提示
- DROP
- 直接丢弃,不给出任何回应
基本参数和用法
常用格式:
iptables [-t 表名] 选项 [链名] [条件] [-j 控制类型]
iptables –[A|I 链] [-i|o 网络接口] [-p 协议] [-s 来源ip/网域] [-d 目标ip/网域] –j[ACCEPT|DROP]
| 参数 | 作用 |
|---|---|
| -P | 设置默认策略:iptables -P INPUT (DROP|ACCEPT) |
| -F | 清空规则链 |
| -L | 查看规则链 |
| -A | 在规则链的末尾加入新规则 |
| -I num | 在规则链的头部加入新规则 |
| -D num | 删除某一条规则 |
| -s | 匹配来源地址IP/MASK,加叹号"!"表示除这个IP外。 |
| -d | 匹配目标地址 |
| -i 网卡名称 | 匹配从这块网卡流入的数据 |
| -o 网卡名称 | 匹配从这块网卡流出的数据 |
| -p | 匹配协议,如tcp,udp,icmp |
| --dport num | 匹配目标端口号 |
| --sport num | 匹配来源端口号 |
查看规则
[root@localhost ~]# iptables [-t tables] [-L] [-nv]
参数:
-t 后面接table,例如nat或filter,如果省略,默认显示filter
-L 列出目前的table的规则
-n 不进行IP与主机名的反查,显示信息的速度会快很多
-v 列出更多的信息,包括封包数,相关网络接口等
删除规则
[root@localhost ~]# iptables [-t tables] [-FXZ]
参数:
-F 清除所有的规则
-X 清除所有自定义规则
-Z 将计数与流量统计清零
默认策略修改 [root@localhost ~]# iptables [-t tables] -P [链名] [ACCEPT/DROP] 案例:
[root@localhost ~]# iptables -A INPUT -i lo -j ACCEPT
# 所有的来自 lo 这个网口的封包,都予以接受
[root@localhost ~]# iptables -A INPUT -s 192.168.1.200 -j ACCEPT
# 目标来自 192.168.1.200 这个 IP 的封包都予以接受
[root@localhost ~]# iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT
[root@localhost ~]# iptables -A INPUT -s 192.168.1.10 -j DROP
# 192.168.1.0/24 可接受,但 192.168.1.10 丢弃
[root@localhost ~]# iptables -L -n --line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
2 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
3 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
4 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
5 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
6 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
7 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
8 ACCEPT all -- 192.168.1.200 0.0.0.0/0
9 ACCEPT all -- 192.168.1.0/24 0.0.0.0/0
10 DROP all -- 192.168.1.10 0.0.0.0/0
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
[root@localhost ~]# iptables -D INPUT 10
# 删掉INPUT中第10条规则
iptables 开放tcp、udp端口
例:开放samba端口(udp137,138;tcp139,445)
[root@localhost ~]# iptables –A INPUT –i eth0 –p udp –dport 137:138 –j ACCEPT
[root@localhost ~]# iptables –A INPUT –i eth0 –p tcp –dport 139 –j ACCEPT
[root@localhost ~]# iptables –A INPUT –i eth0 –p tcp –dport 445 –j ACCEPT
iptables匹配ICMP端口和ICMP类型
iptables –A INPUT –p icmp –icmp-type 类型 –j ACCEPT
参数:--icmp-type :后面必须要接 ICMP 的封包类型,也可以使用代号,
例如 8 代表 echo request 的意思。(可自查询ICMP-type对应表)
Iptables --syn的处理方式
指定TCP匹配扩展
使用 --tcp-flags 选项可以根据tcp包的标志位进行过滤。
[root@localhost ~]# iptables -A INPUT -p tcp --tcp-flags SYN,FIN,ACK SYN
[root@localhost ~]# iptables -A FROWARD -p tcp --tcp-flags ALL SYN,ACK
上实例中第一个表示SYN、ACK、FIN的标志都检查,但是只有SYN匹配。第二个表示ALL(SYN,ACK,FIN,RST,URG,PSH)的标志都检查,但是只有设置了SYN和ACK的匹配。
[root@localhost ~]# iptables -A FORWARD -p tcp --syn
选项--syn相当于"--tcp-flags SYN,RST,ACK SYN"的简写。
[root@localhost ~]# iptables -A INPUT -m 模块名 --state 状态
参数:
-m iptables的模块
state: 状态检查
mac:网卡硬件地址
--state 连接追踪中的状态:
NEW: 新建立一个会话
ESTABLISHED:已建立的连接
RELATED: 有关联关系的连接
INVALID: 无法识别的连接
[root@localhost ~]# iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
# 放行ssh的首次连接状态
[root@localhost ~]# iptables -A INPUT -m mac --mac-source 00:0C:29:56:A6:A2 -j ACCEPT
# 对局域网内mac地址为00:0C:29:56:A6:A2主机开放其联机
保存与恢复
iptables-save > /etc/sysconfig/iptables
iptables-restore < /etc/sysconfig/iptables
转发本地端口
[root@localhost ~]# iptables -t nat -A PREROUTING -p tcp --dport 6666 -j REDIRECT --to-port 22
NAT
- 先经过 NAT table 的 PREROUTING 链;
- 经由路由判断确定这个封包是要进入本机与否,若不进入本机,则下一步;
- 再经过 Filter table 的 FORWARD 链;
- 通过 NAT table 的 POSTROUTING 链,最后传送出去。
NAT 主机的重点就在于上面流程的第 1,4 步骤,也就是 NAT table 的两条重要的链:PREROUTING 与POSTROUTING。 那这两条链重要功能在于修改IP,而这两条链修改的IP又是不一样的,POSTROUTING在修改来源IP,PREROUTING则在修改目标IP 。由于修改的 IP 不一样,所以就称为来源NAT (Source NAT, SNAT) 及目标 NAT (Destination NAT, DNAT)。
[root@localhost ~]# echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
[root@localhost ~]# sysctl -w net.ipv4.ip_forward=1
[root@localhost ~]# sysctl -p
[root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.12.0/24 -j SNAT --to-source 10.1.0.59
# 下面这条是PAT
[root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.12.0/24 -j MASQUERADE
映射内网服务
[root@localhost ~]# iptables -t nat -A PREROUTING -p tcp --dport 8822 -j DNAT --to-destination 192.168.12.2:22
用户权限管理
Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统。 为了更加方便的管理多个用户,就出现了用户组的概念,关于用户和用户组:
- 系统上的每个进程(运行的程是作为特定用户运行
- 每个文件是由一个特定的用户拥有
- 访问文件和目录受到用户的限制
- 与正在运行的进程相关联的用户确定该进程可访问的文件和目录
实现用户账号的管理,要完成的工作主要有如下几个方面:
- 用户账号的添加、删除与修改
- 用户口令的管理
- 用户组的管理
用户和用户组查看
id
用于显示用户的ID,以及所属群组的ID id会显示用户以及所属群组的实际与有效ID。若两个ID相同,则仅显示实际ID。若仅指定用户名称,则显示目前用户的ID。 id [OPTION]... [USER]
- -g:显示用户所属群组的ID。
- -G:显示用户所属附加群组的ID。
- -n:显示用户,所属群组或附加群组的名称。
- -r:显示实际ID。
- -u:显示用户ID。
uid的约定
Linux操作系统会依据用户的uid数值来判定这个用户的角色,分别如下
- 0:超级管理员,也就是root,在linux系统中拥有所有权力
- 1~999:系统用户,系统用户往往是用来约束系统中的服务的
- 1000+:普通用户,可以用来登陆和使用Linux操作系统
关于root用户
- uid是0
- 拥有操作系统所有权力
- 该用户有权力覆盖文件系统上的普通权限
- 安装或删除软件并管理系统文件和目录
- 大多数设备只能由root控制
实例
- 查看当前登陆的用户信息
┌──(root㉿kali)-[~]
└─# id
uid=0(root) gid=0(root) 组=0(root)
- 查看文件的拥有者
┌──(root㉿kali)-[~]
└─# ll /etc/hosts
-rw-r--r-- 1 root root 199 2023年 6月 8日 /etc/hosts

- 查看运行进程的用户名,ps命令会在后面进程管理部分讲解
┌──(root㉿kali)-[~]
└─# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 2 0.0 0.0 0 0 ? S 09:06 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 09:06 0:01 [ksoftirqd/0]
root 4 0.1 0.0 0 0 ? R 09:06 0:09 [kworker/0:0]
root 5 0.0 0.0 0 0 ? S< 09:06 0:00 [kworker/0:0H]
相关的文件
之前说过Linux一切皆文件,所以用户和用户组相关的信息也都是保存在文本文件中的,下面列举出相关的文件。
passwd文件
用于保存用户的信息,一般第一行是root用户,下面都是其他用户,可以通过篡改 passwd 文件提权。
┌──(root㉿kali)-[~]
└─# head -n 1 /etc/passwd
root:x:0:0:root:/root:/bin/bash
# 这个格式为用户名:密码:uid:gid:描述:家目录:登陆后执行的命令
shadow文件
格式中密码占位置太长了,所以使用x来替代,Linux系统会到shadow中查找x部分的的密码内容
┌──(root㉿kali)-[~]
└─# head -n 1 /etc/shadow
root:$6$frokclXSnQa8EbKs$pWElbjPlmxjYh30tr8qLsTQVOhuPg7GmW9Sanm2yXAK8TNMgje1gyc/vwPgqvmSMf6VaoEvveM0gFvtETmXy/.::0:99999:7:::
# 这个格式为用户名:加密密码:最后一次修改时间:最小修改时间间隔:密码有效期:密码需要变更前的警告天数:密码过期后的宽限时间:账号失效时间:保留字段
格式不需要大家记住,只需要知道关于这个用户的密码和有效期都在这个文件中即可。密码在passwd文件中会使用加密算法加密,所以别想知道我的密码是什么,加密算法默认是$6,这个类型6的加密算法是sha-512。我们也可以在man手册中看到对shadow文件的详细解释。
┌──(root㉿kali)-[~]
└─# man 5 shadow
# man手册一个有9个章节,其中第5个章节是对文件格式的说明
# 对man手册感兴趣的同学,也可以自己在网上查找学习man手册的更多内容
┌──(root㉿kali)-[~]
└─# man 5 crypt
# $6是sha512的加密算法
# 后面是加密的盐
group文件
用户和组的对应关系,会保存在group文件中
┌──(root㉿kali)-[~]
└─# head -n 1 /etc/group
root:x:0:
# 这个格式是组名:口令:组标识号:组内用户列表
用户组管理
添加用户组:groupadd
groupadd 命令用于创建一个新的工作组,新工作组的信息将被添加到系统文件中 groupadd [选项] 组
选项
- -g:指定新建工作组的 id;
- -r:创建系统工作组,系统工作组的组ID小于 500;
- -K:覆盖配置文件/etc/login.defs
- -o:允许添加组 ID 号不唯一的工作组。
- -f:如果指定的组已经存在,此选项将失明了仅以成功状态退出。当与 -g 一起使用,并且指定的GID_MIN已经存在时,选择另一个唯一的GID(即-g关闭)。
实例
- 按照下图创建组,并且指定gid,并且检查是否成功

┌──(root㉿kali)-[~]
└─# groupadd hr -g 1001
┌──(root㉿kali)-[~]
└─# groupadd sale -g 2001
┌──(root㉿kali)-[~]
└─# groupadd it -g 3001
┌──(root㉿kali)-[~]
└─# groupadd fd -g 4001
┌──(root㉿kali)-[~]
└─# tail -n 4 /etc/group
hr:x:1001:
sale:x:2001:
it:x:3001:
fd:x:4001:
修改用户组:groupmod
groupmod命令用于更改群组识别码或名称 groupmod [选项] 组
选项
- -g:将组 ID 改为 GID
- -n:改名为 NEW_GROUP
- -o:允许使用重复的 GID
实例
- 修改fd组的名字为finance
┌──(root㉿kali)-[~]
└─# groupmod -n finance fd
┌──(root㉿kali)-[~]
└─# tail -n 1 /etc/group
finance:x:4001:
删除用户组:groupdel
groupdel命令用于删除群组 需要从系统上删除群组时,可用groupdel(group delete)指令来完成这项工作。倘若该群组中仍包括某些用户,则必须先删除这些用户后,方能删除群组。 groupdel [组名]
实例
- 删除一个用户组
┌──(root㉿kali)-[~]
└─# groupadd test
┌──(root㉿kali)-[~]
└─# groupdel test
用户组成员管理:gpasswd
gpasswd 是 Linux 下工作组文件 /etc/group 和 /etc/gshadow 管理工具,用于将一个用户添加到组或者从组中删除 gpasswd [选项] 组
选项
- -a:添加用户到组;
- -d:从组删除用户;
- -A:指定管理员;
- -M:指定组成员和-A的用途差不多;
-R:限制用户登入组,只有组中的成员才可以用newgrp加入该组。
实例
创建用户itadmin,并且将其加入it组
┌──(root㉿kali)-[~]
└─# useradd itadmin
┌──(root㉿kali)-[~]
└─# gpasswd -a itadmin it
正在将用户“itadmin”加入到“it”组中
┌──(root㉿kali)-[~]
└─# cat /etc/group |grep it
it:x:3001:itadmin
# 在组文件中,可以看到这个组的成员
┌──(root㉿kali)-[~]
└─# id itadmin
uid=1001(itadmin) gid=4002(itadmin) 组=4002(itadmin),3001(it)
# 在用户的信息中,可以看到这个用户的所属组
┌──(root㉿kali)-[~]
└─# gpasswd -d itadmin it
正在将用户“itadmin”从“it”组中删除
用户管理
添加用户:useradd
useradd可以用来添加新的用户账号 useradd [选项] 用户名
选项
- -c comment:指定一段注释性描述。
- -d 目录:指定用户主目录,如果此目录不存在,则同时使用-m选项,可以创建主目录。
- -m:创建用户的主目录
- -g 用户组:指定用户所属的用户组,默认会创建一个和用户名同名的用户组。
- -G 用户组:用户组 指定用户所属的附加组,一个用户可以属于多个附加组。
- -s Shell文件:指定用户的登录Shell。
-u 用户号:指定用户的用户号,如果同时有-o选项,则可以重复使用其他用户的标识号。
实例
添加一般用户
┌──(root㉿kali)-[~]
└─# useradd -d /home/user01 -m -s /usr/bin/zsh user01
- 为添加的用户指定相应的用户组
┌──(root㉿kali)-[~]
└─# useradd -g root -d /home/user02 -m -s /usr/bin/zsh user02
- 建立一个不给登录的用户
┌──(root㉿kali)-[~]
└─# useradd -s /sbin/nologin user03
修改用户:usermod
usermod命令用于修改用户帐号 usermod可用来修改用户帐号的各项设定 usermod [选项] 登录
选项
- -c<备注>:修改用户帐号的备注文字。
- -a:追加,默认的修改是覆盖
- -d登入目录>:修改用户登入时的目录。
- -e<有效期限>:修改帐号的有效期限。
- -f<缓冲天数>:修改在密码过期后多少天即关闭该帐号。
- -g<群组>:修改用户所属的群组。
- -G<群组>:修改用户所属的附加群组。
- -l<帐号名称>:修改用户帐号名称。
- -L:锁定用户密码,使密码无效。
- -s\
:修改用户登入后所使用的shell。 - -u\
:修改用户ID。 - -U:解除密码锁定。
实例
- 更改登录的目录
┌──(root㉿kali)-[~]
└─# usermod -d /home user01
┌──(root㉿kali)-[~]
└─# su - user01
$ pwd
/home
$
- 改变用户的uid
┌──(root㉿kali)-[~]
└─# usermod -u 6666 user02
删除用户:userdel
userdel命令用于删除用户帐号 userdel可删除用户帐号与相关的文件。若不加参数,则仅删除用户帐号,而不删除相关文件 userdel [-r] [用户帐号]
选项
- -r:删除用户登入目录以及目录中所有文件
实例
- 删除用户账号
┌──(root㉿kali)-[~]
└─# userdel user03
- 删除用户账户和家目录
┌──(root㉿kali)-[~]
└─# userdel -r user02
passwd文件中的shell
查看/etc/passwd文件会发现在每行的最后是登录成功之后执行的命令,有两种是使用最为频繁的:
- /bin/bash:这个是Linux的命令行工具,我们正常登陆之后默认就是进入命令行
- /sbin/nologin:如果写成nologin,那么用户将无法登录,有些用户是作为进程权限管理而存在的,不需要登录。如果提供登录的功能反而不安全,所以写成nologin
┌──(root㉿kali)-[~]
└─# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
我们可以新建一个用户,然后尝试自定义登录成功之后执行的命令,用来加深印象。
┌──(root㉿kali)-[~]
└─# useradd -s /usr/bin/date test01
┌──(root㉿kali)-[~]
└─# tail -n 1 /etc/passwd
test01:x:6667:6667::/home/test01:/usr/bin/date
切换到test01用户,会发现自动显示时间,说明最后的这个段内容就是用户登录之后会运行的程序

用户密码管理
root用户可以直接设置普通用户密码,普通用户必须要提供原密码,才可以修改自己密码。
passwd
passwd 命令用来更改使用者的密码
passwd [选项...] <帐号名称>
选项
- -k:保持身份验证令牌不过期
- -d:删除已命名帐号的密码(只有根用户才能进行此操作)
- -l:锁定指名帐户的密码(仅限 root 用户)
- -u:解锁指名账户的密码(仅限 root 用户)
- -x:密码的最长有效时限(只有根用户才能进行此操作)
- -n:密码的最短有效时限(只有根用户才能进行此操作)
- -w:在密码过期前多少天开始提醒用户(只有根用户才能进行此操作)
- -i:当密码过期后经过多少天该帐号会被禁用(只有根用户才能进行此操作)
- -S:报告已命名帐号的密码状态(只有根用户才能进行此操作)
- --stdin:从标准输入读取令牌(只有根用户才能进行此操作,kali的passwd程序并未提供此选项)
实例
- 修改test01用户密码
┌──(root㉿kali)-[~]
└─# passwd test01
新的密码:
重新输入新的密码:
passwd:已成功更新密码
- 锁定user01
┌──(root㉿kali)-[~]
└─# passwd -l user01
passwd:密码已更改。
# 然后就无法远程登录了,但是已经在线的情况不会掉线
┌──(root㉿kali)-[~]
└─# passwd -u user01
passwd:密码已更改。
# 解锁
- 让user01下次登录强制改密码
┌──(root㉿kali)-[~]
└─# passwd -e user01
passwd:密码已更改。
- login.defs文件
/etc/login.defs文件是用来创建用户时进行一定的限制,但是优先级低于/etc/passwd和/etc/shadow,如果有冲突的地方,系统会以/etc/passwd和/etc/shadow为准 下面是这个文件的内容,egrep命令我们后续会讲到,这边可以理解为不看文件的注释和空行。
┌──(root㉿kali)-[~]
└─# egrep -v '^[ ]*$|^#' /etc/login.defs
# egrep 相当于grep -E,是加入正则表达式的功能
# -v 表示排除显示被匹配上的行
# ^[ ]*$|^# 空行和以#开头的行将被匹配上
MAIL_DIR /var/mail # 系统消息(邮件)文件夹
PASS_MAX_DAYS 99999 # 密码有效最大天数
PASS_MIN_DAYS 0 # 密码有效最小天数
PASS_MIN_LEN 5 # 密码长度
PASS_WARN_AGE 7 # 密码失效警告倒计时
UID_MIN 1000 # 用户UID最小1000
UID_MAX 60000 # 用户UID最大60000
SYS_UID_MIN 201 # 系统用户UID最小201
SYS_UID_MAX 999 # 系统用户UID最大999
GID_MIN 1000 # 用户组GID最小1000
GID_MAX 60000 # 用户组GID最大60000
SYS_GID_MIN 201
SYS_GID_MAX 999
CREATE_HOME yes # 创建家目录
UMASK 077 # 创建文件/目录的权限掩码
USERGROUPS_ENAB yes # 创建用户时同时生成组是 如果此处是no 创建的用户 会是gid=100(users)groups=100(users)
ENCRYPT_METHOD SHA512 # 加密 方法 sha 512 这个方法生成的密码在/etc/shadow里面的第二列会以$6$开头
chage
chage是用于更改用户密码过期信息
chage [选项] 登录
选项
- -d:将最近一次密码设置时间设为“最近日期”
- -E 过期日期:将帐户过期时间设为“过期日期”
- -I INACITVE:过期 INACTIVE 天数后,设定密码为失效状态
- -l:显示帐户年龄信息
- -m 最小天数:将两次改变密码之间相距的最小天数设为“最小天数”
- -M 最大天数:将两次改变密码之间相距的最大天数设为“最大天数”
-W 警告天数:将过期警告天数设为“警告天数”
实例
强制用户在下次登录的时候换密码
┌──(root㉿kali)-[~]
└─# chage -d 0 user01
┌──(root㉿kali)-[~]
└─# su - user01
您必须立即更改密码(管理员强制)。
为 user01 更改 STRESS 密码。
当前的密码:
小知识:当你新建用户的时候,用户的home目录下会有一些默认的隐藏文件,这些隐藏文件是在创建用户的时候从/etc/skel/中复制过去Y的。
文件权限管理
文件权限设置:可以赋予某个用户或组,能够以何种方式,访问某个文件 Linux 系统是一种典型的多用户系统,不同的用户处于不同的地位,拥有不同的权限。 为了保护系统的安全性,Linux 系统对不同的用户访问同一文件(包括目录文件)的权限做了不同的规定。 在 Linux 中我们通常使用以下两个命令来修改文件或目录的所属用户与权限:
- chown (change ownerp) : 修改所属用户与组。
- chmod (change mode) : 修改用户的权限。
在 Linux 中我们可以使用 ll 或者 ls –l 命令来显示一个文件的属性以及文件所属的用户和组
每个文件的属性由左边第一部分的 10 个字符来确定(如下图)。
从左至右用 0-9 这些数字来表示。
- 第 0 位确定文件类型,第 1-3 位确定属主(该文件的所有者)拥有该文件的权限。
- 第4-6位确定属组(所有者的同组用户)拥有该文件的权限,第7-9位确定其他用户拥有该文件的权限。
- 其中,第 1、4、7 位表示读权限,如果用r字符表示,则有读权限,如果用-字符表示,则没有读权限;
- 第 2、5、8 位表示写权限,如果用w字符表示,则有写权限,如果用-字符表示没有写权限;第 3、6、9 位表示可执行权限,如果用x字符表示,则有执行权限,如果用-字符表示,则没有执行权限。
修改文件属主chown
chown用于设置文件所有者和文件关联组的命令 chown 需要超级用户root的权限才能执行此命令 chown [选项]... [所有者] [:[组]] 文件...
选项
- -R: 处理指定目录以及其子目录下的所有文件
- -v: 显示详细的处理信息
实例
- 设置所有者为user01,组为hr
┌──(root㉿kali)-[~]
└─# touch file
┌──(root㉿kali)-[~]
└─# chown user01:hr file
┌──(root㉿kali)-[~]
└─# ll file
-rw-r--r-- 1 user01 hr 0 5月23日 15:01 file
- 将目录dir1下的所有文件拥有者设置为user01,允许使用的组设置为it
┌──(root㉿kali)-[~]
└─# mkdir dir1
┌──(root㉿kali)-[~]
└─# cd dir1
┌──(root㉿kali)-[~/dir1]
└─# touch file{a..z}
┌──(root㉿kali)-[~/dir1]
└─# cd ..
┌──(root㉿kali)-[~]
└─# chown -R user01:it dir1/*
┌──(root㉿kali)-[~]
└─# ll dir1/
修改文件权限chmod
chmod是控制用户对文件的权限的命令 chmod [选项]... 模式[,模式]... 文件...
模式
mode : 权限设定字串,格式如下 : [ugoa...] [[+-=] [rwx]...] [,...]
- u表示该文件的拥有者,g表示与该文件的拥有者属于同一个群体(group)者,o表示其他以外的人,a表示这三者皆是。
- +表示增加权限、-表示取消权限、=表示唯一设定权限。
- r表示可读取,w表示可写入,x表示可执行
- r
wx权限对文件和目录的意义 | 权限 | 对文件的影响 | 对目录的影响 | | --- | --- | --- | | r(读取) | 可以读取文件的内容 | 可以列出目录的内容(文件名),可以使用ls命令 | | w(写入) | 可以更改文件的内容 | 可以创建或删除目录中的任一文件,可以使用touch、rm命令 | | x(可执行) | 可以作为命令执行文件 | 可以访问目录的内容(取决于目录中文件的权限),可以使用cd命令 |
┌──(root㉿kali)-[~/dir1]
└─# chmod g=rw file
┌──(root㉿kali)-[~/dir1]
└─# ll
总计 0
-rwxrw-r-- 1 root root 0 5月23日 15:04 file
┌──(root㉿kali)-[~/dir1]
└─# chmod o=- file
┌──(root㉿kali)-[~/dir1]
└─# ll
总计 0
-rwxrw---- 1 root root 0 5月23日 15:04 file
┌──(root㉿kali)-[~/dir1]
└─# chmod u-w file
┌──(root㉿kali)-[~/dir1]
└─# ll
总计 0
-r-xrw---- 1 root root 0 5月23日 15:04 file
八进制语法
chmod命令可以使用八进制数来指定权限。文件或目录的权限位是由9个权限位来控制,每三位为一组,它们分别是文件所有者(User)的读、写、执行,用户组(Group)的读、写、执行以及其它用户(Other)的读、写、执行。历史上,文件权限被放在一个比特掩码中,掩码中指定的比特位设为1,用来说明一个类具有相应的优先级。
| # | 权限 | rwx | 二进制 |
|---|---|---|---|
| 7 | 读 + 写 + 执行 | rwx | 111 |
| 6 | 读 + 写 | rw- | 110 |
| 5 | 读 + 执行 | r-x | 101 |
| 4 | 只读 | r-- | 100 |
| 3 | 写 + 执行 | -wx | 011 |
| 2 | 只写 | -w- | 010 |
| 1 | 只执行 | --x | 001 |
| 0 | 无 | --- | 000 |
例如, 765 将这样解释:
- 所有者的权限用数字表达:属主的那三个权限位的数字加起来的总和。如 rwx ,也就是 4+2+1 ,应该是 7。
- 用户组的权限用数字表达:属组的那个权限位数字的相加的总和。如 rw- ,也就是 4+2+0 ,应该是 6。
- 其它用户的权限数字表达:其它用户权限位的数字相加的总和。如 r-x ,也就是 4+0+1 ,应该是 5。
选项
- -f: 若该文件权限无法被更改也不要显示错误讯息
- -v: 显示权限变更的详细资料
- -R: 对目前目录下的所有文件与子目录进行相同的权限变更(即以递归的方式逐个变更)
实例
- 限制用户user01对file文件的写入
┌──(root㉿kali)-[~/dir1]
└─# su - user01
┌──(user01㉿kali)-[~]
└─$ touch file
┌──(user01㉿kali)-[~]
└─$ ll file
-rw-r--r-- 1 user01 user01 0 5月23日 15:07 file
┌──(user01㉿kali)-[~]
└─$ chmod 444 file
┌──(user01㉿kali)-[~]
└─$ ll
总计 0
-r--r--r-- 1 user01 user01 0 5月23日 15:07 file
┌──(user01㉿kali)-[~]
└─$ echo "hello" >> file
zsh: 权限不够: file
- 限制用户user01删除dir目录下的文件
┌──(user01㉿kali)-[~]
└─$ mkdir dir
┌──(user01㉿kali)-[~]
└─$ touch dir/file
┌──(user01㉿kali)-[~]
└─$ ll -d dir
drwxr-xr-x 2 user01 user01 4096 5月23日 15:09 dir
┌──(user01㉿kali)-[~]
└─$ chmod 555 dir
┌──(user01㉿kali)-[~]
└─$ ll -d dir
dr-xr-xr-x 2 user01 user01 4096 5月23日 15:09 dir
┌──(user01㉿kali)-[~]
└─$ rm -rf dir/file
rm: 无法删除 'dir/file': 权限不够
对目录有w权限,可以在目录中创建新文件,可以删除文件夹中的文件(跟文件权限无关),至于为什么可以这样,我们在磁盘管理的部分讲解。
文件访问控制列表
文件访问控制列表(File Access Control Lists,FACL)是Linux开的一套新的文件系统权限管理方法。 传统的Linux文件系统的权限控制是通过user、group、other与r(读)、w(写)、x(执行)的不同组合来实现的。随着应用的发展,这些权限组合已不能适应现时复杂的文件系统权限控制要求。例如,我们可能需把一个文件的读权限和写权限分别赋予两个不同的用户或一个用户和一个组这样的组合。传统的权限管理设置起来就力不从心了。 文件访问控制列表可以针对文件单独设置某个用户或者用户组队文件的管理权限。
getfacl命名
获取文件访问控制列表的详细内容 getfacl [-aceEsRLPtpndvh] file ...
选项
- -a:仅显示文件访问控制列表
- -d:仅显示默认的访问控制列表
- -c:不显示注释表头
- -e:显示所有的有效权限
- -E:显示无效权限
- -R:递归显示子目录
- -t:使用制表符分隔的输出格式
实例
- 查看acl权限列表
[root@localhost ~]# getfacl anaconda-ks.cfg
# file: anaconda-ks.cfg
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
- 查看acl权限列表,不显示注释表头
[root@localhost ~]# getfacl -c anaconda-ks.cfg
user::rwx
group::r-x
other::r-x
setfacl命令
用来设置更精确的文件权限 setfacl [-bkndRLP] { -m|-M|-x|-X ... } file ...
选项
- -m:更改文件的访问控制列表
- -M:从文件读取访问控制列表条目更改
- -x:根据文件中访问控制列表移除条目
- -X:从文件读取访问控制列表条目并删除
- -b:删除所有扩展访问控制列表条目
- -k:移除默认访问控制列表
- -d:应用到默认访问控制列表的操作
- -R:递归操作子目录
实例
- 给指定用户添加acl权限
- 给user01单独添加file的rw权限
┌──(root㉿kali)-[/tmp/dir1]
└─# setfacl -m u:user01:rw file
┌──(root㉿kali)-[/tmp/dir1]
└─# getfacl file
# file: file
# owner: root
# group: root
user::rw-
user:user01:rw-
group::r-x
mask::rwx
other::---
- 移除user01的访问控制列表权限
┌──(root㉿kali)-[/tmp/dir1]
└─# setfacl -x u:user01 file
┌──(root㉿kali)-[/tmp/dir1]
└─# getfacl -c file
user::rw-
group::r-x
mask::r-x
other::---
- 创建group01组,然后给这个组访问acl的权限,将user01加入group01组验证是否成功
┌──(root㉿kali)-[/tmp/dir1]
└─# groupadd group01
┌──(root㉿kali)-[/tmp/dir1]
└─# setfacl -m g:group01:rwx file
┌──(root㉿kali)-[/tmp/dir1]
└─# usermod -aG group01 user01
┌──(root㉿kali)-[/tmp/dir1]
└─# id user01
uid=6670(user01) gid=6670(user01) 组=6670(user01),6674(group01)
┌──(root㉿kali)-[/tmp/dir1]
└─# getfacl file
# file: file
# owner: root
# group: root
user::rw-
group::r-x
group:group01:rwx
mask::rwx
other::---
# user01需要重新登录让组生效
┌──(user01㉿kali)-[/tmp/dir1]
└─$ cat file
hello world
- 对dir1设置的acl权限并不会被之后在dir1下创建的子文件和子目录继承,可以设置默认ACL权限,来让目录下面的新建文件和文件夹都继承父目录的权限
┌──(root㉿kali)-[/tmp/dir1]
└─# setfacl -m d:u:user01:rw ../dir1
┌──(root㉿kali)-[/tmp/dir1]
└─# getfacl -c ../dir1
user::rwx
group::r-x
other::r-x
default:user::rwx
default:user:user01:rw-
default:group::r-x
default:mask::rwx
default:other::r-x
┌──(root㉿kali)-[/tmp/dir1]
└─# touch file1
┌──(root㉿kali)-[/tmp/dir1]
└─# getfacl -c file1
user::rw-
user:user01:rw-
group::r-x #effective:r--
mask::rw-
other::r--
mask有效权限
mask 权限,指的是用户或群组能拥有的最大 ACL 权限,也就是说,给用户或群组设定的 ACL 权限不能超过 mask 规定的权限范围,超出部分做无效处理。 注意上面的案例,在newfile的facl中,有一个mask权限是rw-,所以我们即使给了user01 r-x权限,在实际生效的时候,x也不会有的,注意后面的提示#effective:r--表示x权限并没有赋予。
实例
- 修改上面案例中的newfile的mask权限
┌──(root㉿kali)-[/tmp/dir1]
└─# setfacl -m m::rwx file1
┌──(root㉿kali)-[/tmp/dir1]
└─# getfacl -c file1
user::rw-
user:user01:rw-
group::r-x
mask::rwx
other::r--
特殊权限
文件除了上述的r,w,x权限以外,还有三个特殊权限:suid,sgid,sticky
suid
suid 属性只能运用在可执行文件上,含义是开放文件所有者的权限给其他用户,即当用户执行该执行文件时,会拥有该执行文件所有者的权限。如果给一个非二进制文件文件附加suid权限,则会显示大写S,属于无效。 普通用户能够执行passwd命令修改自己的密码,修改密码其实就是修改/etc/shadow这个文件,查看/etc/passwd这个文件的权限,发现除了root其他人没有写权限,但是普通用户能够成功执行passwd,其原因就在于passwd这个命令的权限是rwsrw----,其中s的作用就是让执行命令的人具有和该命令拥有者相同的权限。
[root@localhost ~]# ll /usr/bin/passwd
-rwsr-xr-x. 1 root root 27832 6月 10 2014 /usr/bin/passwd
实例
- 如果错误的配置了suid就会让普通用户能够以root身份运行程序
┌──(root㉿kali)-[/tmp/dir1]
└─# chmod u+s /usr/bin/whoami
# 此时user01普通用户执行whoami就是root
┌──(user01㉿kali)-[/tmp/dir1]
└─$ whoami
root
- 切换成普通用户输入修改密码命令
┌──(user01㉿kali)-[/tmp/dir1]
└─$ passwd
为 user01 更改 STRESS 密码。
当前的密码:
- 保持这个会话别端口,新建一个ssh会话,查看系统进程,可以看到当前是调用root用户执行的passwd命令
┌──(root㉿kali)-[/tmp/dir1]
└─# ps aux |grep passwd
root 24490 0.0 0.0 9060 3588 pts/6 S+ 15:38 0:00 passwd
- 如果想自己添加suid权限,可以输入下面两个命令
chmod u+s file
chmod 4765 file
sgid
sgid 属性可运用于文件或者目录,运用在文件的含义是开放文件所属组的权限给其他用户,即当用户执行该执行文件时,会拥有该执行文件所属组用户的权限。如果给一个非二进制文件文件附加sgid权限,则会显示大写S,属于无效。 运用在目录上的含义是,在该目录下所有用户创建的文件或者目录的所属组都和其一样。即如果/home/user1目录具有sgid权限,且所属组是user1,则任何用户在/home/user1下创建的子目录或者文件的所属组都是user1。
实例
- 设置sgid,让用户在workdir下创建的文件都属于worker组
┌──(root㉿kali)-[/tmp/dir1]
└─# chmod g+s dir
┌──(root㉿kali)-[/tmp/dir1]
└─# ll -d dir
drwxrwsr-x+ 2 root root 4096 5月23日 15:55 dir
┌──(root㉿kali)-[/tmp/dir1]
└─# chown root:hr dir
┌──(root㉿kali)-[/tmp/dir1]
└─# ll -d dir
drwxrwsr-x+ 2 root hr 4096 5月23日 15:55 dir
┌──(root㉿kali)-[/tmp/dir1]
└─# cd dir
┌──(root㉿kali)-[/tmp/dir1/dir]
└─# touch file
┌──(root㉿kali)-[/tmp/dir1/dir]
└─# ll
总计 0
-rw-rw-r--+ 1 root hr 0 5月23日 15:55 file
sticky
sticky 权限只能运用于目录上,含义是该目录下所有的文件和子目录只能由所属者删除,即使其的权限是777或者其他。一个公共目录,每个人都可以创建文件,删除自己的文件,但不能删除别人的文件(仅对目录有效)。
实例
- 设置sticky,让普通用户只能创建文件,不能删除文件
┌──(root㉿kali)-[/tmp]
└─# chmod 777 dir1
┌──(root㉿kali)-[/tmp]
└─# cd dir1/
┌──(root㉿kali)-[/tmp/dir1]
└─# touch file
# 此时这个file是可以被user01删除的
┌──(root㉿kali)-[/tmp/dir1]
└─# cd ..
┌──(root㉿kali)-[/tmp]
└─# chmod o+t dir1/
# 此时user01只能删除自己的文件,不能再删除其他用户的文件了
sudoers
Linux是多用户多任务的操作系统, 共享该系统的用户往往不只一个。出于安全性考虑, 有必要通过useradd创建一些非root用户, 只让它们拥有不完全的权限; 如有必要,再来提升权限执行。 sudo就是来解决这个需求的: 这些非root用户不需要知道root的密码,就可以提权到root,执行一些root才能执行的命令。 sudo [选项] [用户名] [命令]
sudo命令执行过程
- 当用户执行sudo时,系统会主动寻找/etc/sudoers文件,判断该用户是否有执行sudo的权限
- 确认用户具有可执行sudo的权限后,让用户输入用户自己的密码确认
- 若密码输入成功,则开始执行sudo后续的命令
赋予用户sudo操作的权限
通过useradd添加的用户,并不具备sudo权限。在ubuntu/centos等系统下, 需要将用户加入admin组或者wheel组或者sudo组。以root用户身份执行如下命令, 将用户加入wheel/admin/sudo组。
usermod -a -G sudo <用户名>
如果提示sudo组不存在, 则还需要先创建该组
groupadd sudo
配置文件
sudo的权限控制可以在/etc/sudoers文件中查看到。一般来说,通过cat /etc/sudoers指令来查看该文件, 会看到如下几行代码。
┌──(root㉿kali)-[~]
└─# egrep -v '^[ ]*$|^#' /etc/sudoers
=====省略=====
root ALL=(ALL) ALL
%sudo ALL=(ALL) ALL
对/etc/sudoers文件进行编辑的代码公式可以概括为
授权用户/组 主机=[(切换到哪些用户或组)] [是否需要输入密码验证] 命令1,命令2,...
字段1 字段2 =[(字段3)] [字段4] 字段5
凡是[ ]中的内容, 都能省略; 命令和命令之间用,号分隔,字段3、字段4,是可以省略的。
- "字段1"不以%号开头的表示"将要授权的用户",以%号开头的表示"将要授权的组"。
- "字段2"表示允许登录的主机, ALL表示所有,;如果该字段不为ALL,表示授权用户只能在某些机器上登录本服务器来执行sudo命令
- 比如:jack mycomputer=/usr/sbin/reboot,/usr/sbin/shutdown表示: 普通用户jack在主机(或主机组)mycomputer上, 可以通过sudo执行reboot和shutdown两个命令
- "字段3"如果省略, 相当于(root:root),表示可以通过sudo提权到root,如果为(ALL)或者(ALL:ALL), 表示能够提权到(任意用户:任意用户组)。
- "字段4"的可能取值是NOPASSWD:。请注意NOPASSWD后面带有冒号:。表示执行sudo时可以不需要输入密码。
- 比如:lucy ALL=(ALL) NOPASSWD: /bin/useradd表示: 普通用户lucy可以在任何主机上, 通过sudo执行/bin/useradd命令, 并且不需要输入密码
- 比如:peter ALL=(ALL) NOPASSWD: ALL,表示: 普通用户peter可以在任何主机上, 通过sudo执行任何命令, 并且不需要输入密码。
- "字段5"是使用逗号分开一系列命令,这些命令就是授权给用户的操作; ALL表示允许所有操作。命令都是使用绝对路径, 这是为了避免目录下有同名命令被执行,从而造成安全隐患。
- 如果你将授权写成如下安全性欠妥的格式:lucy ALL=(ALL) chown,chmod,useradd那么用户就有可能创建一个他自己的程序, 也命名为userad, 然后放在它的本地路径中, 如此一来他就能够使用root来执行这个"名为useradd的程序"。这是相当危险的!
编辑配置文件
在实践中,去编辑/etc/sudoers文件,系统提示我没权限,这是因为/etc/sudoers的内容如此敏感,以至于该文件是只读的。所以,编辑该文件前,请确认清楚你知道自己正在做什么。 强烈建议通过visudo命令来修改该文件,通过visudo修改,如果配置出错,会有提示。 官方文档推荐的做法,不是直接修改/etc/sudoers文件,而是将修改写在/etc/sudoers.d/目录下的文件中。如果使用这种方式修改sudoers,需要在/etc/sudoers文件的最后行,加上#includedir /etc/sudoers.d一行(默认已有)。需要注意,这个#includedir /etc/sudoers.d中的#并不是注释,请勿修改。
export EDITOR="vim"
# 可以使用这个变量来修改默认的visudo的编辑器
visudo
选项
- -u:以指定用户或 ID 运行命令(或编辑文件)
- -l:显示出自己(执行 sudo 的使用者)的权限
- -b:将要执行的指令放在后台执行
- -i: 以目标用户身份运行一个登录 shell;可同时指定一条命令。相当于切换到root,不过只需要用户自己的密码即可。
实例
- 以管理员身份查看shadow文件
┌──(root㉿kali)-[~]
└─# useradd user
┌──(root㉿kali)-[~]
└─# passwd user
# 需要给user设置密码,后面才可以使用sudo
┌──(root㉿kali)-[~]
└─# su - user
# 切换过来之后,由于kali环境变量的问题,可能会出现提示符消失的情况
user@kali:~$ id
uid=6668(user) gid=6668(user) 组=6668(user)
# 当前并不是sudo组成员
user@kali:~$ sudo apt -y install vim
[sudo] user 的密码:
user 不是 sudoers 文件。
# 没有sudo权限
user@kali:~$ exit
┌──(root㉿kali)-[~]
└─# usermod -a -G sudo user
# 加入sudo组
┌──(root㉿kali)-[~]
└─# su - user
user@kali:~$ sudo apt -y install vim
[sudo] user 的密码:
正在读取软件包列表... 完成
正在分析软件包的依赖关系树... 完成
正在读取状态信息... 完成
......
user@kali:~$ sudo whoami
root
# 加入sudo以后,拥有了借用root执行命令的权限
user@kali:~$ cat /etc/shadow
cat: /etc/shadow: 权限不够
user@kali:~$ sudo cat /etc/shadow
# 能够借助root用户来执行cat
- 查看下列示例
papi ALL=(root:root) NOPASSWD:/usr/bin/chown, PASSWD:/usr/sbin/useradd
- 表示: 用户papi能在所有可能出现的主机上, 提权到root下执行
/bin/chown, 不必输入密码; 但运行/usr/sbin/useradd命令时需要密码- 在具有sudo操作的用户下, 执行
sudo -l可以查看到该用户被允许和被禁止运行的命令
- 查看下列示例
papi ALL=/usr/sbin/,/sbin/,!/usr/sbin/fdisk
- 命令前面加上!号表示取消该命令
- 用户papi在所有可能出现的主机上, 能够运行目录/usr/sbin和/sbin下所有的程序, 但fdisk除外。
- 默认情况下输入一次sudo可以保持15分钟不再要求输入密码,如果想要延长这个时间,可以修改配置文件
[root@localhost ~]# visudo
Defaults env_reset,pwfeedback,timestamp_timeout=60
# 这个是改成60分钟才会需要再次输入密码,并且输入密码的时候会显示*号
- 可以使用
sudo -i切换到sudo状态下,每条命令都会默认加上sudo
chattr文件属性
chattr命令用于改变文件属性。 这项指令可改变存放在文件或目录属性,这些属性共有以下8种模式:
- a:让文件或目录仅供附加用途
- b:不更新文件或目录的最后存取时间
- c:将文件或目录压缩后存放
- d:将文件或目录排除在倾倒操作之外
- i:不得任意更动文件或目录
- s:保密性删除文件或目录
- S:即时更新文件或目录
- u:预防意外删除
chattr [-RV] [+/-/=<属性>] [文件或目录...]
选项
- -R:递归处理,将指定目录下的所有文件及子目录一并处理
- -v <版本编号>:设置文件或目录版本
- -V:显示指令执行过程
- + <属性>:开启文件或目录的该项属性
- - <属性>:关闭文件或目录的该项属性
- = <属性>:指定文件或目录的该项属性
实例
- 用chattr命令防止系统中某个关键文件被修改
┌──(root㉿kali)-[/tmp/dir1]
└─# touch vip.file
┌──(root㉿kali)-[/tmp/dir1]
└─# chattr +i vip.file
┌──(root㉿kali)-[/tmp/dir1]
└─# lsattr vip.file
----i---------e------- vip.file
┌──(root㉿kali)-[/tmp/dir1]
└─# echo "hello" > vip.file
bash: vip.file: 不允许的操作
- 让某个文件只能往里面追加数据,但不能删除,适用于各种日志文件
┌──(root㉿kali)-[/tmp/dir1]
└─# touch logs
┌──(root㉿kali)-[/tmp/dir1]
└─# chattr +a logs
┌──(root㉿kali)-[/tmp/dir1]
└─# lsattr logs
-----a--------e------- logs
┌──(root㉿kali)-[/tmp/dir1]
└─# echo "lalal" > logs # 覆盖是不可以的
bash: logs: 不允许的操作
┌──(root㉿kali)-[/tmp/dir1]
└─# echo "lalal" >> logs # 追加是允许的
umask
umask命令指定在建立文件时预设的权限掩码,进程 新建文件、目录的默认权限会收到umask的影响,umask表示要减掉得到权限。 umask可用来设定[权限掩码]。[权限掩码]是由3个八进制的数字所组成,将现有的存取权限减掉权限掩码后,即可产生建立文件时预设的权限。 umask [选项] [权限掩码]
选项
┌──(root㉿kali)-[/tmp/dir1]
└─# umask -S
u=rwx,g=rx,o=rx
- 修改umask的数值(临时)
┌──(root㉿kali)-[/tmp/dir1]
└─# umask 0000
┌──(root㉿kali)-[/tmp/dir1]
└─# mkdir dir
┌──(root㉿kali)-[/tmp/dir1]
└─# ll
总计 1
drwxrwxrwx 2 root root 4096 5月23日 16:23 dir
- 修改umask的数值(永久)
[root@localhost ~]# vim /etc/profile
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
umask 002
else
umask 022
fi
[root@localhost ~]# source /etc/profile # 立即在当前shell中生效
- 通过umask决定新建用户HOME目录的权限
[root@localhost ~]# vim /etc/login.defs
# The permission mask is initialized to this value. If not specified,
# the permission mask will be initialized to 022.
UMASK 077
进程
进程是一个在系统中运行的程序
进程是已启动的可执行程序的运行实例,进程有以下组成部分
- 已分配内存的地址空间
- 安全属性,包括所有权凭据和特权
- 进程代码的一个或多个执行线程
- 进程状态
程序:二进制文件,静态/bin/date,/usr/sbin/httpd,/usr/sbin/sshd,/usr/local/nginx/sbin/ngix
进程:是程序运行的过程,动态,有生命周期及运行状态
进程类型
守护进程:在系统引导过程中启动的进程,跟终端无关的进程
前台进程:跟终端相关,通过终端启动的进程
进程的生命周期
![]()
父进程复制自己的地址空间(fork)创建一个新的(子)进程结构。每个新进程分配一个唯一的进程ID(PID),满足跟踪安全性之需。PID和父进程ID(PPID)是子进程环境的元素,任何进程都可以创建子进程,所有进程都是第一个系统进程的后代。
systemd简介
首先 systmed 是一个用户空间的程序,属于应用程序,不属于 Linux 内核范畴。Systemd 是 Linux 系统中最新的初始化系统(init),它主要的设计目标是克服 sysvinit(这个是centos6中的初始化系统)固有的缺点,提高系统的启动速度。
Linux内核加载启动后,用户空间的第一个进程就是初始化进程,这个程序的物理文件约定位于/sbin/init,当然也可以通过传递内核参数来让内核启动指定的程序。这个进程的特点是进程号为1,代表第一个运行的用户空间进程。不同发行版采用了不同的启动程序,主要有以下几种主流选择:
- 以 Ubuntu 为代表的 Linux 发行版采用 upstart
- centos7.0 版本之前的 System V init
- centos7.0 版本的 systemd
centos7上所有的进程都是systemd的后代,systemd的功能繁多,不仅用来管理服务,还可以管理挂载点,定义定时任务等。这些工作都是由编辑相应的配置单元文件完成的。
systemd unit 类型
systemd需要管理的功能比较多,所以支持的配置单元类型也比较繁多,我们在日常使用Linux的过程中对系统服务的管理最多,所以我们主要了解一下service类型即可,其他类型作为一个了解,下面列举出所有类型详细的解释。
| 单元类型 | 文件格式 | 描述 |
|---|---|---|
| Service unit | .service | 服务类 |
| Target unit | .target | 一个 unit 服务组,用于模拟实现运行级别 |
| Automount unit | .automount | 文件系统自动挂载点 |
| Device unit | .device | 内核识别的设备文件 |
| Mount unit | .mount | 文件系统挂载点 |
| Path unit | .path | 文件或目录 |
| Scope unit | .scope | 外部创建的进程 |
| Slice unit | .slice | A group of hierarchically organized units that manage system processes. |
| Snapshot unit | .snapshot | 系统快照 |
| Socket unit | .socket | 套接字 |
| Swap unit | .swap | 标识 swap 设备 |
| Timer unit | .timer | systemd 的计时器 |
unit 文件保存位置
我们目前了解到文件所在的位置即可,关于文件内部的格式与如何修改这些文件,我们会在后续的服务搭建过程中细讲。
| 目录 | 描述 |
|---|---|
| /usr/lib/systemd/system/ | RPM 包安装时分发的 unit 文件 |
| /run/systemd/system/ | systemd 运行时创建的文件 |
| /etc/systemd/system/ | systemctl enable 创建的 unit 文件 |
管理系统服务
systemd 的主要命令行工具是systemctl
systemctl [选项...] {命令} ...
systemctl常用命令
这边列举出来的命令会在后面的学习过程中经常用到,所以大家只要对本部分中系统管理的命令合集有一个影响即可。
| 命令 | 描述 |
|---|---|
| systemctl start name.service | 启动服务 |
| systemctl stop name.service | 停止服务 |
| systemctl restart name.service | 重启服务(没启动的服务会启动) |
| systemctl try-restart name.service | 只重启正在运行的服务 |
| systemctl reload name.service | 重载配置文件 |
| systemctl status name.service systemctl is-active name.service | 检查服务状态检查服务是否启动 |
| systemctl list-units --type service --all | 显示所有的服务状态 |
| systemctl enable name.service | 启用开机自启服务 |
| systemctl disable name.service | 停用自启服务 |
| systemctl status name.service systemctl is-enabled name.service | 检查服务状态查看服务是否自启 |
| systemctl list-unit-files --type service | 查看所有服务 |
| systemctl list-dependencies --after | 列出在指定服务之前启动的服务(依赖) |
| systemctl list-dependencies --before | 列出在指定服务之后启动的服务(被依赖) |
一个服务设置为开机启动使用会将/usr/lib/systemd/system/name.service软链接到/etc/systemd/system/,但是 enable 命令不会重写已经存在的链接,所以当我们修改了服务文件就需要重新加载:
┌──(root㉿kali)-[~]
└─# systemctl enable --now apache2
┌──(root㉿kali)-[~]
└─# systemctl start apache2
┌──(root㉿kali)-[~]
└─# systemctl restart apache2
┌──(root㉿kali)-[~]
└─# systemctl stop apache2
┌──(root㉿kali)-[~]
└─# systemctl disable --now apache2
ps
ps命令用于显示当前进程的状态,类似于 windows 的任务管理器
ps [选项]
选项
- -A:列出所有的进程
- -e:列出所有的进程
- -f:显示不包含资源使用率的相关信息
- ‐H:以进程层级格式显示进程相关信息
- -w:显示加宽可以显示较多的信息
- -u:显示较详细的信息
- -x:显示其他使用者的行程
显示信息的格式说明
| 列名 | 说明 |
|---|---|
| USER | 进程拥有者 |
| PID | 进程ID |
| %CPU | 占用的 CPU 使用率 |
| %MEM | 占用的内存使用率 |
| VSZ | 占用的虚拟内存大小 |
| RSS | 占用的常驻内存大小 |
| TTY | 执行的终端编号 |
| STAT | 该进程的状态* |
| START | 进程开始时间 |
| TIME | CPU使用时间 |
| COMMAND | 所执行的命令 |
*STAT表示的进程状态有如下几种:
- D: 无法中断的休眠状态 ,将一直等待事件的发生或等待某种系统资源
- R: 正在执行中
- S: 可中断状态
- T: 暂停执行
- Z: 不存在但暂时无法消除,也叫僵尸进程
- 每个进程在运行结束后都会处于僵死状态,等待父进程调用进而释放系统资源,处于该状态的进程已经运行结束,但是它的父进程还没有释放其系统资源
- W: 没有足够的内存可分配
- <: 高优先序的进程
- N: 低优先序的进程
- +:前台进程
- l:多线程进程
- s:主进程(先导进程)
实例
- 查看进程以层级格式(类似于pstree命令)
[root@localhost ~]# ps -efH
[root@Python-Test-CentOS7 system]# ps -efH
UID PID PPID C STIME TTY TIME CMD
root 2 0 0 14:26 ? 00:00:00 [kthreadd]
root 4 2 0 14:26 ? 00:00:00 [kworker/0:0H]
root 5 2 0 14:26 ? 00:00:00 [kworker/u128:0]
==============以下省略==================
- 按照CPU使用率排序查看所有进程
[root@localhost ~]# ps aux --sort %cpu # 递增
[root@localhost ~]# ps aux --sort -%cpu # 递减
- 按照实际内存使用排序查看所有进程
[root@localhost ~]# ps aux --sort rss # 递增
[root@localhost ~]# ps aux --sort -rss # 递减
- 按照父子进程显示ssh服务的层级关系
[root@localhost ~]# ps auxf |grep sshd
# ps -efH
root 6814 0.0 0.2 112756 4320 ? Ss 09:06 0:00 /usr/sbin/sshd -D
root 7097 0.0 0.2 158760 5576 ? Ss 09:06 0:00 \_ sshd: root@pts/0
root 7337 0.1 0.2 158760 5588 ? Ss 10:21 0:00 \_ sshd: root@pts/1
root 7364 0.0 0.0 112724 988 pts/1 S+ 10:24 0:00 \_ grep --color=auto sshd
- 自定义显示格式
[root@localhost ~]# ps -axo user,pid,ppid,%mem,%cpu,command --sort -%cpu
- 查看指定进程的PID,多种查看的方式
[root@localhost ~]# cat /run/sshd.pid
[root@localhost ~]# ps aux |grep sshd
[root@localhost ~]# pgrep -l sshd
[root@localhost ~]# pidof sshd
- ps查看进程树
┌──(root㉿kali)-[~]
└─# apt-get install psmisc
┌──(root㉿kali)-[~]
└─# pstree
┌──(root㉿kali)-[~]
└─# pstree -p
┌──(root㉿kali)-[~]
└─# pstree --help
top
top命令用于实时显示 process 的动态
top [选项]
选项
- -d: 改变显示的更新速度,或是在交互式指令列( interactive command)按 s
- -c: 切换显示模式,共有两种模式,一是只显示程序的名称,另一种是显示完整的路径与名称
- -S: 累积模式,会将己完成或消失的子行程 ( dead child process ) 的 CPU time 累积起来
- -s: 安全模式,将交互式指令取消, 避免潜在的危机
- -i: 不显示任何闲置 (idle) 或无用 (zombie) 的行程
- -n: 更新的次数,完成后将会退出 top
- -b: 显示模式,搭配 "n" 参数一起使用,可以用来将 top 的结果输出到文件内
交互模式快捷键
| 快捷键 | 功能 |
|---|---|
| 空格 | 立即刷新 |
| P | 根据CPU使用多少排序 |
| T | 根据时间、累计排序 |
| q | 退出top命令 |
| m | 切换显示内存信息 |
| t | 切换显示进程和CPU状态信息 |
| c | 切换显示命令名称和完整命令行 |
| M | 根据内存的大小排序 |
| W | 将当前设置写入 ~/.toprc 文件中,这是top配置文件推荐方法 |
| N | 以PID的大小排序 |
| z | 彩色 |
实例
- 显示进程信息,每个1秒钟刷新一次
[root@localhost ~]# top -d 1
- 显示完整命令
[root@localhost ~]# top -c
- 更新两次后终止更新显示
[root@localhost ~]# top -n 2
- 显示指定的进程信息
[root@localhost ~]# top -p 7097
kill
kill 命令用于删除执行中的程序或工作
kill 可将指定的信号送至程序。预设的信号为 SIGTERM(15),可将指定程序终止
kill [-s <信息名称或编号>][程序] 或 kill [-l <信息编号>]
选项
- -l <信号编号>: 若不加<信号编号>选项,则 -l 参数会列出全部的信号名称
- -s <信号名称或编号>:指定要送出的信息
- [程序]:[程序]可以是程序的PID或是PGID
使用 kill -l 命令列出所有可用信号,最常用的信号如下
| 编号 | 信号名 | 作用 |
|---|---|---|
| 1 | SIGHUP | 重新加载配置 |
| 2 | SIGINT | 键盘中断^C |
| 3 | SIGQUIT | 键盘退出 |
| 9 | SIGKILL | 强制终止 |
| 15 | SIGTERM | 终止(正常结束),缺省信号 |
| 18 | SIGCONT | 继续 |
| 19 | SIGSTOP | 停止 |
| 20 | SIGTSTP | 暂停^Z |
实例
- 杀死所有的ping命令,在linux命令中,使用反引号`包含的命令会优先执行,并将执行的结果作为参数提供给命令。
[root@localhost ~]# kill `pgrep ping`
- 强制杀死进程
[root@localhost ~]# kill -KILL 123456
[root@localhost ~]# kill -9 123456
- 重新加载配置
[root@localhost ~]# kill -HUP pid
[root@localhost ~]# kill -1 pid
pkill
pkill 用于杀死一个进程,与 kill 不同的是它会杀死指定名字的所有进程,类似于 killall 命令
pkill [选项] name
选项
- name: 进程名
- -u:指定用户名
- -t:指定终端
实例
- 结束所有的sshd进程
[root@localhost ~]# pkill sshd
- 结束用户user1的所有进程
[root@localhost ~]# pkill -u user1
- 终止pts/2上所有进程
[root@localhost ~]# pkill -t pts/2
- 终止pts/2上所有进程,并结束pts/2
[root@localhost ~]# pkill -9 -t pts/2
- 查看远程登录用户,并踢出用户
[root@localhost ~]# w
15:02:26 up 5:21, 2 users, load average: 0.05, 0.03, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root tty1 14:41 20:34 0.02s 0.02s -bash
root pts/0 192.168.175.1 14:42 2.00s 0.05s 0.01s w
user1 pts/1 192.168.175.1 14:40 20:34 0.02s 0.02s -bash
[root@localhost ~]# pkill -u user1
nice
nice命令用来修改程序的优先级别,如果未指定程序,则会显示目前程序的优先级别,默认的nice值为 0,范围为 -20(最高优先级别)到 19(最低优先级别)。
nice数字越小,表示程序会越优先被处理,在系统运行缓慢的时候,nice值越小的进程会有越高的优先处理级别。
nice [选项] [参数]...
Linux进程调度及多任务
每个CPU(或CPU核心)在一个时间点上只能处理一个进程,通过时间片技术,Linux实际能够运行的进程(和线程数)可以超出实际可用的CPU及核心数量。Linux内核进程调度程序将多个进程在CPU核心上快速切换,从而给用户多个进程在同时运行的假象。
通过调整程序在计算机中的优先级别,可以让程序在时间片中占有更长的时间,从而获得更快的处理速度
选项
- -n
:设置nice值
实例
- 将 ls 的优先级设置为 1 并执行
[root@localhost ~]# nice -n 1 ls
- 将 ls 的优先级加 10 并执行,默认是设置为10
[root@localhost ~]# nice ls
PRI
在top命令中可以看到有PR这个数值,PR 和 nice 值,都会影响进程执行的优先级。PR 由 OS 内核动态调整,用户不能调整(PR 值越低,进程执行的优先级越高)。
nice值用户可以自己调整,在用户调整了nice值后系统会通过如下公式来调整新的PR值,从而确定这个进程在系统中的优先级
PR(新) = PR(旧) + nice
PR值是OS动态调整的,但是PR的最终值还是需要由OS分析决定的
jobs
jobs 命令可以用来查看当前终端放入后台的任务
jobs [-lnprs] [任务声明 ...]
将任务放入到后台
Linux 命令放入后台的方法有两种:
- 在命令后面加入
空格 &。使用这种方法放入后台的命令,在后台处于执行状态 - 命令执行过裎中按 Ctrl+Z 快捷键,命令在后台处于暂停状态
实例
- 将任务放入后台,然后查看任务
- "+"号代表最近一个放入后台的工作,也是工作恢复时默认恢复的工作
- "-"号代表倒数第二个放入后台的工作
[root@localhost ~]# top &
[root@localhost ~]# vi &
[root@localhost ~]# ping baidu.com > /dev/null &
# 让ping运行,但是不显示结果
[root@localhost ~]# jobs
[1] 已停止 top
[2]- 已停止 vi
[3]+ 运行中 ping baidu.com > /dev/null &
将任务恢复到前台
fg 命令用于把后台工作恢复到前台执行
fg %工作号
注意,在使用此命令时,% 可以省略,但若将% 工作号全部省略,则此命令会将带有 + 号的工作恢复到前台。另外,使用此命令的过程中, % 可有可无。
实例
- 将top恢复到前台
- 命令虽然是对的,但是top这种需要交互的任务是无法后台的,所以也恢复不了
[root@localhost ~]# top &
[1] 20584
[root@localhost ~]# jobs
[1]+ 已停止 top
[root@localhost ~]# fg 1
后台任务恢复到后台运行
前面讲过,使用Ctrl+z快捷键的方式,可以将前台工作放入后台,但是会处于暂停状态,可以使用bg命令
bg %工作号
这里的 % 可以省略
实例
- 将ping命令暂停到后台,然后恢复后台运行
[root@localhost ~]# ping baidu.com > /dev/null
^Z # 这边按下了Ctrl+z
[1]+ 已停止 ping baidu.com > /dev/null
[root@localhost ~]# jobs
[1]+ 已停止 ping baidu.com > /dev/null
[root@localhost ~]# bg %1
[1]+ ping baidu.com > /dev/null &
[root@localhost ~]# jobs
[1]+ 运行中 ping baidu.com > /dev/null &
nohup
虽然可以将程序放在后台运行,但是一旦关闭远程连接那么程序就会中断,如果我们想要将程序一直保持在后台运行,那么我们可以有如下三个选择:
- 把需要在后台执行的命令加入
/etc/rc.local文件,让系统在启动时执行这个后台程序。这种方法的问题是,服务器是不能随便重启的,如果有临时后台任务,就不能执行了 - 使用系统定时任务,让系统在指定的时间执行某个后台命令。这样放入后台的命令与终端无关,是不依赖登录终端的
- 使用 nohup 命令
nohup 命令&
注意,这里的‘&’表示此命令会在终端后台工作;反之,如果没有‘&’,则表示此命令会在终端前台工作。
实例
- 让一个任务后台运行
[root@localhost ~]# nohup ping baidu.com &
我们退出远程连接,然后重新登录回来,会看到ping baidu.com依旧在运行,查看~/nohup.out文件可以看到程序执行输出的内容
[root@localhost ~]# ps aux |grep ping
root 7157 0.0 0.0 149968 1988 ? S 14:12 0:00 ping baidu.com
[root@localhost ~]# tail -f nohup.out