Linux 系统和 Windows 系统之间的软件包是分开的。Windows 系统中的 .exe,.msi 是无法在Linux系统下运行。Linux 系统中的服务器应用是无法在 Windows 系统下运行。
Windows 下的 .exe 程序就是经过编译过后的二进制程序,类似于 Linux 下的 rpm 包。本质就是将源码包编译成二进制程序。反编译实现起来会非常困难。
(脚本安装包)
软件包选择建议:
源码包,如果服务是给大量客户端提供访问的,建议使用源码包,源码包效率更高(例如:LAMP)
RPM包,如果程序是给少量用户访问,或者本地使用的,建议RPM包,因为RPM简单,并且管理方便。
~ vim hello.c
#include
int main (void)
{
printf ("hello world\n");
}
~ rpm -ivh /mnt/cdrom/Packages/gcc-4.4.6-4.el6.i686.rpm
~ gcc -c hello.c
# -c 生成".o"头文件。这里会生成 hello.o 头文件,但是不会生成执行文件
~ gcc -o hello hello.o
# -o 生成执行文件,并制定执行文件名。这里生成的hello就是可执行文件
~ ./hello
hello world
# 执行 hello 文件
源码包的优点是:
源码包有缺点吗?
RPM包的优点:
RPM包的缺点:

1)树形依赖:a-——->b–—->c
2)环形依赖:a-——->b-——->c-——->a(需要一条命令同时安装)
3)模块依赖:
什么是模块依赖?我们举一个例子,尝试安装以下文件:
[root@localhost Packages]# rpm -ivh mysql-connector-odbc-5.2.5-7.el7.x86_64.rpm
错误:依赖检测失败:
libodbc.so.2()(64bit) 被 mysql-connector-odbc-5.2.5-7.e17.x86_64 需要
libodbcinst.so.2()(64bit) 被 mysql-connector-odbc-5.2.5-7.el7.x86_64 需要
发现报错,需要安装“libodbc.so.2”函数库文件,这时会发现在光盘中根本找不到这个文件。那是因为函数库没有单独成包,是包含在某一个软件包中的。而如果要知道在哪个软件包中,需要查询网站 www. rpmfind.net,如图:

包全名:httpd-2.2.15-15.el6.centos.i686.rpm
包名:httpd
httpd :软件包名
2.2.15 :软件版本
15 :软件发布的次数
el6 :软件发行商。el6是RedHat公司发布,适合RHEL6.x(Red Hat Enterprise Linux)和CentOS6.x下使用
i686 :适合的硬件平台。RPM包可以在不同的硬件平台安装,选择适合不同CPU的软件版本,可以最大化的发挥CPU性能,所以出现了所谓的i386 (386 以上计算机都可以安装)、i586 (586以上的计算机都可以安装)、i686(奔腾II 以上计算机都可以安装,目前所有的CPU都是奔腾II以上,所以这个软件版本居多)、x86_64 (64位CPU可以安装)和noarch(没有硬件限制)等文件名了。
rpm :rpm包的扩展名。我们说过Linux下文件不是靠扩展名区分文件类型,也就是Linux中扩展名没有任何含义。可是这里怎么又出现了扩展名呢﹖原因很简单,如果我不把RPM的扩展名叫做“.rpm”,管理员很难知道这是一个RPM包,当然也就无法正确安装了。也就是说如果RPM包不用“.rpm”作为扩展名,系统可以正确识别没有问题,可是管理员很难识别这是个什么样的软件。
参考 1.3.3 RPM 包的依赖,不再重复
| RPM 包默认安装路径 | |
|---|---|
| /etc/ | 配置文件安装目录 |
| /usr/bin/ | 可执行的命令安装目录 |
| /usr/lib/ | 程序所使用的函数库保存位置 |
| /usr/share/doc/ | 基本的软件使用手册保存位置 |
| /usr/share/man/ | 帮助文件保存位置 |
1)安装命令
rpm -ivh 包全名
#注意一定是包全名。如果跟包全名的命令要注意路径,因为软件包在光盘当中
选项:
-i :install安装(install)
-v :显示更详细的信息(verbose)
-h :打印#显示安装进度(hash)
RPM 包建议安装在默认路径中(作者决定的)
1)默认安装位置是系统的习惯位置
2)RPM包管理系统是有 rpm -e 卸载命令的( 数据库记录安装位置 /var/lib/rpm )
源码包一定要指定安装位置的,源码包不指定安装位置,那么将会安装到Linux系统的各个目录下,但是源码包安装是没有数据库记录的,源码包的卸载直接卸载相关的目录即可。
~ rpm -ivh httpd-*
httpd-2.4.6-95.el7.centos.x86_64.rpm httpd-manual-2.4.6-95.el7.centos.noarch.rpm
httpd-devel-2.4.6-95.el7.centos.x86_64.rpm httpd-tools-2.4.6-95.el7.centos.x86_64.rpm
# 根据所需要的依赖进行依赖安装即可
yum localinstall -y httpd-2.4.6-95.el7.centos.x86_64.rpm \
httpd-devel-2.4.6-95.el7.centos.x86_64.rpm \
httpd-manual-2.4.6-95.el7.centos.noarch.rpm \
httpd-tools-2.4.6-95.el7.centos.x86_64.rpm
2)服务启动
[root@localhost ~]# service 服务名 start|stop|restart|status
参数:
start :启动服务
stop :停止服务
restart :重启服务
status :查看服务状态
~ systemctl start httpd
~ ss -ntlp | grep 80
LISTEN 0 128 [::]:80 [::]:* users:(("httpd",pid=21546,fd=4),("httpd",pid=21545,fd=4),("httpd",pid=21544,fd=4),("httpd",pid=21543,fd=4),("httpd",pid=21542,fd=4),("httpd",pid=21541,fd=4))
~ curl localhost
# 可以显示相应的返回值
RPM 包安装的 Apache
CentOS6 1)service httpd restart
CentOS6 2)/etc/rc.d/init.d/httpd start | restart | stop
CentOS7 1)systemctl restart httpd
/var/www/html :Apache 的网页路径
是否需要重启服务,唯一标准:就是是否修改了对应的配置文件。
~ echo "Hello world" > /var/www/html/index.html
~ curl localhost
Hello world
/etc/httpd/conf/httpd.conf
[root@localhost~]# rpm -Uvh 包全名
选项:
-U(大写) 升级安装,如果没有安装过(可以代替 rpm -ivh),系统直接安装。如果安装过的版本较旧,则
升级到新版本(upgrade),升级加安装。
[root@localhost~]# rpm -Fvh 包全名
选项:
-F(大写) 升级安装,如果没有安装过,则不会安装。必须安装有较旧版本,才能升级(freshen)
RPM 卸载的时候会出现依赖性的问题。
[root@localhost ~]# rpm -e 包名
选项:
--nodeps :不检查依赖性,生产环境下不能使用该参数
-e :卸载
# 不要使用 yum 命令进行卸载软件
yum 可以取代 rpm 的安装,升级等操作,但是在查询中推荐使用 rpm 命令。
RPM 命令查询是客户端 本地软件包是否安装
YUM 命令查询时服务器端 服务端的软件包的信息
1)查询软件包是否安装
可以查询软件包是否安装,命令格式如下:
~ rpm -q 包名
选项:
-q:查询(query)
范例:
~ rpm -q httpd
package httpd is not installed
~ rpm -q httpd
httpd-2.2.15-69.el6.centos.x86_64
2)查询系统中的所有安装软件包
可以查询Linux系统中所有已经安装的软件包,命令格式如下:
~ rpm -qa
选项:
-a:所有(all)
当然,可以用管道符来查看所需的内容,比如:
~ rpm -qa | grep http
httpd-tools-2.2.15-69.el6.centos.x86_64
httpd-2.2.15-69.el6.centos.x86_64
你会发现,使用“rpm -q包名”只能查看这个包是否安装,但是使用“rpm -qa / grep 包名”会把包含包名称的所有包都列出来。
3)查询软件包的详细信息
可以查询已经安装的某个软件包的详细信息,命令格式如下:
~ rpm -qi 包名
选项:
-i:查询软件信息(information)
范例:
~ rpm -qi httpd
Name : httpd Relocations: (not relocatable)
Version : 2.2.15 Vendor: CentOS
Release : 69.el6.centos Build Date: Tue 19 Jun 2018 11:45:51 PM CST
Install Date: Sun 19 Jun 2022 05:22:02 PM CST Build Host: x86-01.bsys.centos.org
Group : System Environment/Daemons Source RPM: httpd-2.2.15-69.el6.centos.src.rpm
Size : 3170514 License: ASL 2.0
Signature : RSA/SHA1, Wed 20 Jun 2018 07:36:47 PM CST, Key ID 0946fca2c105b9de
Packager : CentOS BuildSystem <http://bugs.centos.org>
URL : http://httpd.apache.org/
Summary : Apache HTTP Server
Description :
The Apache HTTP Server is a powerful, efficient, and extensible
web server.
也可以查询还没有安装的软件包的详细信息,命令格式如下:
~ rpm -qip 包全名
选项:
-p:查询没有安装的软件包(Package)
范例:
~ rpm -qip httpd-2.2.15-69.el6.centos.x86_64.rpm
warning: httpd-2.2.15-69.el6.centos.x86_64.rpm: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY
Name : httpd Relocations: (not relocatable)
Version : 2.2.15 Vendor: CentOS
Release : 69.el6.centos Build Date: Tue 19 Jun 2018 11:45:51 PM CST
Install Date: (not installed) Build Host: x86-01.bsys.centos.org
Group : System Environment/Daemons Source RPM: httpd-2.2.15-69.el6.centos.src.rpm
Size : 3170514 License: ASL 2.0
Signature : RSA/SHA1, Wed 20 Jun 2018 07:36:47 PM CST, Key ID 0946fca2c105b9de
Packager : CentOS BuildSystem <http://bugs.centos.org>
URL : http://httpd.apache.org/
Summary : Apache HTTP Server
Description :
The Apache HTTP Server is a powerful, efficient, and extensible
web server.
4)查询软件包中的文件列表
可以查询已经安装的软件包中的文件列表和安装的完整目录,命令格式如下:
~ rpm -ql 包名
选项:
-l:列出软件包中所有的文件列表和软件所安装的目录(list)
那么,可以查询还没有安装的软件包中的文件列表和打算安装的位置吗?答案是可以,命令格式如下:
~ rpm -qlp 包全名
选项:
-p:查询没有安装的软件包(Package)
范例:
~ rpm -qlp httpd-2.2.15-69.el6.centos.x86_64.rpm
5)查询系统文件属于哪个RPM包
既然可以知道每个RPM包中的文件的安装位置,那么可以查询系统文件属于哪个RPM包吗?当然可以,不过需要注意的是,手工建立的文件是不能查询的,因为这些文件不是通过RPM包安装的,当然不能反向查询它属于哪个RPM包。命令格式如下:
~ rpm -qf 系统文件名
选项:
-f:查询系统文件属于哪个软件包(file)
范例:
~ rpm -qf /etc/fstab
setup-2.8.14-23.el6.noarch
6)查询软件包所依赖的软件包
查询系统中和已经安装的软件包有依赖关系的软件包,命令格式如下:
~ rpm -qR 包名
选项:
-R:查询软件包的依赖性(requires)
可以查询没有安装的软件包的依赖性吗?加“-p”选项即可。例如,查看一下还没有安装的bind软件包的依赖包,可以执行如下命令:
~ rpm -qRp /mnt/cdrom/Packages/bind-9.8.2-0.68.rc1.el6.x86_64.rpm
小总结:
RPM 包:
手工命令安装
YUM 在线安装
1)基本命令
~ rpm -Va
选项:
-Va:校验本机已经安装的所有软件包
~ rpm -V 已安装的包名
选项:
-V:校验指定 PRM 包中的文件(verify)
~ rpm -Vf 系统文件名
选项:
-Vf:校验某个系统文件是否被修改
2)验证举例
~ rpm -V httpd
S.5....T. c /etc/httpd/conf/httpd.conf
验证内容 文件类型 文件名
出现了提示信息,我们来解释下最前面共有8个信息内容,是表示验证内容的。文件名前面的c是表示这是个配置文件(configuration)。最后是文件名。那么验证内容中的8个信息的具体内容如下:
软件包校验是跟软件包的原始值进行对比,就会有可能软件包的原始值会有问题,那么就可以在系统中事先安装好证书,该证书用来保证软件包的原始值是没有问题的。
只有到软件包的原始值通过证书的校验认证,才能允许安装该软件包,否则不通过。
apache配置文件的文件类型是c,那么还有哪些文件类型呢?
MD5 加密算法,会将文件利用 MD5 的加密算法得到一个结果为随机的 16 机制的MD5码。只要文件内容不变,无论在哪台电脑都不会改变。
MD5 只要用于做完整性的校验。
刚刚的校验方法只能对已经安装的RPM包中的文件进行校验,但是如果RPM包本身就被动过手脚,那么校验就不能解决问题了。我们就必须使用数字证书验证了。
数字证书保证原始值的不变。
数字证书有如下特点:
1)数字证书位置
那么数字证书在哪里呢?其实在CentOS 6.3的第一张光盘中就有,当然它默认也会放在系统中。
~ ls -l /mnt/cdrom/RPM-GPG-KEY-CentOS-6
-r--r--r--. 2 root root 1706 Nov 27 2013 /mnt/cdrom/RPM-GPG-KEY-CentOS-6
# 光盘中的数字证书位置
~ ls -l /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
-rw-r--r--. 1 root root 1706 Jun 26 2018 /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
# 系统中的数字证书位置
2)数字证书导入
~ rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
选项:
--import:导入数字证书
我们如何查询系统中安装好的数字证书呢?命令如下:
~ rpm -qa | grep gpg-pubkey
gpg-pubkey-c105b9de-4e0fd3a3
修改配置文件一定要进行备份
1)cpio 命令
cpio命令主要有三种基本模式:“-o”模式指的是 copy-out 模式,就是把数据备份到文件库中;“-i”模式指的是 copy-in 模式,就是把数据从文件库中恢复;“-p”模式指的是复制模式,就是不把数据备份到cpio库中,而是直接复制为其他文件。命令如下:
~ cpio -o[vcB] > [文件|设备]
# 备份
选项:
-o: copy-out模式,备份
-v: 显示备份过程
-c: 使用较新的portable format存储方式
-B: 设定输入输出块为5120bytes,而不是模式的512butes
~ cpio -i[vcdu] < [文件|设备]
# 还原
选项:
-i: copy-in模式,还原
-v:显示还原过程
-c:使用较新的portable format存储方式
-d:还原时自动新建目录
-u:自动使用较新的文件覆盖较旧的文件
~ cpio -p 目标目录
举几个例子吧,先来看看使用cpio备份数据的方法,命令如下:
# 例子:利用 find 命令找到文件,进行备份
~ find /etc/ -print | cpio -ocvB > /root/etc.cpio
# 利用 find 指定要备份 /etc 目录,使用 > 导出到 etc.cpio 文件
~ ls -lh /root/etc.cpio
-rw-r--r-- 1 root root 32M Aug 10 11:01 /root/etc.cpio
# etc.cpio 文件生成
再来看看如何恢复 cpio 的备份数据,命令如下:
~ cpio -idvcu < /root/etc.cpio
#还原etc的备份
#但是如果大家查看下当前日录/root,会发现没有生成 etc目录。
#这是因为备份是/etc目录使用的是绝对路径,所以恢复的数据直接恢复到了/ete系统目录中,而没有生成在/root/etc中。
在Cent0S5.x的版本中,是可以利用上面的命令备份与恢复指定的文件。但是到CentOS6.x当中,需要更加严谨。如果备份时使用绝对路径,则恢复的数据会直接到绝对路径指定的路径中,如果需要把数据恢复到当前目录中,则需要使用相对路径,例如:
# 备份:
~ cd /etc/
# 进入到 /etc/ 目录
~ find . -print | cpio -ocvB > /root/etc.cpio
# 利用 find 指定要备份 /etc 目录,使用 > 导出到 etc.cpio 文件
# 恢复:
~ cd /root
# 回到 /root 目录中
~ mkdir etc_test
# 建立恢复测试目录
~ cd etc_test
# 进入测试目录,数据恢复到此
~ cpio -idvcu < /root/etc.cpio
# 还原/ete目录的数据,因为备份时使用的是相对路径,则会还原到/root/ete_test/目录下
最后来演示一下cpio命令的“-p”复制模式,命令如下:
~ cd /tmp/
# 进入 /tmp 目录
~ rm -rf *
# 删除 /tmp 目录中所有数据
~ mkdir test
# 建立备份目录
~ find /boot/ -print | cpio -p /tmp/test
# 备份 /boot/ 目录到 /tmp/test 目录中
~ ls -l /tmp/test
total 4
dr-xr-xr-x 5 root root 4096 Aug 10 11:12 boot
# 在/tmp/test 目录中备份出了 boot 目录
2)提取 RPM 包中的文件
~ rpm2cpio 包全名 | cpio -idv .文件绝对路径
rpm2cpio 将rpm包转换为cpi格式的命令
cpio 是一个标准工具,它用于创建软件档案文件和从档案文件中提取文件
举个例子,现在我假设把系统中的 /bin/ls 命令不小心误删除了,那么我可以修复回来吗?这时有两种方法修复,要不就是使用 --force 选项覆盖安装一遍 coreutils-8.4-19.e16.i686包,要不就可以使用 cpio 命令提取出/bin/ls命令文件,再把它拷贝到对应位置就可以了。不过我是怎么知道/bin/ls命令是属于 coreutils-8.4-19.e16.i686 这个软件包的呢?还记得 -qf 选项吗?命令如下:
~ rpm -qf /bin/ls
coreutils-8.4-47.el6.x86_64
# 查看 ls 文件属于哪个软件包
那么我们在讲RPM包中文件提取,所以我们使用第二章方法,cpio命令提取出ls命令文件,然后拷贝到对应位置,命令如下:
~ mv /bin/ls /root/
# 把 /bin/ls 命令移动到 /root/ 目录下,造成误删除的假象
~ ls
-bash: /bin/ls: No such file or directory
# 此时执行 ls 命令,系统会报错"命令没有找到"
~ rpm2cpio /mnt/cdrom/Packages/coreutils-8.4-47.el6.x86_64.rpm | cpio -idv ./bin/ls
./bin/ls
25240 blocks
# 提取 ls 命令文件到当前目录下
~ cp /root/bin/ls /bin/
# 把提取ls 命令文件复制到 /bin/ 目录下
~ ls -l
total 120
drwxr-xr-x. 2 root root 4096 Aug 4 06:32 bin
-rwxr-xr-x. 1 root root 117048 Jun 19 2018 ls
yum 源配置文件保存在/etc/yum.repos. d/目录中,文件的扩展名一定是“.repo”。也就是说,yum源配置文件只要扩展名是“.repo”就会生效。
~ ls -l /etc/yum.repos.d/
total 28
-rw-r--r--. 1 root root 1991 Jun 26 2018 CentOS-Base.repo
-rw-r--r--. 1 root root 647 Jun 26 2018 CentOS-Debuginfo.repo
-rw-r--r--. 1 root root 289 Jun 26 2018 CentOS-fasttrack.repo
-rw-r--r--. 1 root root 630 Jun 26 2018 CentOS-Media.repo
-rw-r--r--. 1 root root 8854 Jun 26 2018 CentOS-Vault.repo
这个目录中有5个yum源配置文件,默认情况下Cent0S-Base.repo文件生效。我们打开这个文件看看,命令如下:
~ vim /etc/yum.repos.d/CentOS-Base.repo
[base]
name=CentOS-$releasever - Base
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
#released updates
[updates]
name=CentOS-$releasever - Updates
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
...省略部分输出...
在CentOS-Base.repo文件中有5个yum源容器,这里只列出了base容器,其他容器和 base容器类似。我们解释一下base这个容器。
第一步:放入 CentOS 安装光盘,并挂载光盘到指定位置。命令如下:
~ mkdir -pv /mnt/cdrom
# 创建 cdrom 目录,作为光盘的挂载点
~ mount /dev/cdrom /mnt/cdrom
# 挂载光盘到/mnt/cdrom 目录下
第二步:修改其他几个yum源配置文件的扩展名,让它们失效,因为只有扩展名是“*.repo”的文件才能作为yum源配置文件。当然也可以删除其他几个yum源配置文件,但是如果删除了,当你又想用网络作为yum源时,就没有了参考文件,所以最好还是修改扩展名。命令如下:
~ cd /etc/yum.repos.d
~ mv CentOS-Base.repo CentOS-Base.repo.bak
~ mv CentOS-Debuginfo.repo CentOS-Debuginfo.repo.bak
~ mv CentOS-Vault.repo CentOS-Vault.repo.bak
第三步:修改光盘yum源配置文件CentOS-ISO.repo,参照以下方法修改:
~ vim CentOS-ISO.repo
[CentOS-ISO]
name=CentOS-ISO
baseurl=file:///mnt/cdrom
# 地址为你自己的光盘挂载地址
# file:///media/cdrom/
# file:///media/cdrecorder/
# 注释掉两个不存在的地址
enabled=1
# 把 enabled=0 改为 enabled=1,让这个 yum 源配置文件生效
gpgcheck=1
gpgfile=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
# 将软件包信息提前在本地索引缓存,用来提高搜索安装软件的速度
~ yum makecache fast
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
CentOS-ISO | 4.0 kB 00:00 ...
CentOS-ISO/group_gz | 242 kB 00:00 ...
CentOS-ISO/filelists_db | 6.3 MB 00:00 ...
CentOS-ISO/other_db | 2.8 MB 00:00 ...
Metadata Cache Created
# 显示所有仓库
~ yum repolist
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
repo id repo name status
CentOS-ISO CentOS-ISO 6,713
repolist: 6,713
# 详细信息内容显示
~ yum list
1)查询
~ yum list
# 查询所有可用软件包列表
Installed Packages
# 已经安装的软件包
ConsoleKit.x86_64 0.4.1-6.el6 @anaconda-CentOS-201806291108.x8
6_64/6.10
ConsoleKit-libs.x86_64 0.4.1-6.el6 @anaconda-CentOS-201806291108.x8
6_64/6.10
...省略部分输出...
Available Packages
# 还可以安装的软件包
389-ds-base.x86_64 1.2.11.15-95.el6_9 CentOS-ISO
389-ds-base-devel.i686 1.2.11.15-95.el6_9 CentOS-ISO
# 软件包 版本 所在位置(光盘)
...省略部分输出...
~ yum list 包名
# 查询单个软件包
# 例如:
~ yum list samba
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
Available Packages
samba.x86_64 3.6.23-51.el6 CentOS-ISO
~ yum search 关键字
# 搜索服务器上所有和关键字相关的软件包
# 例如
~ yum search ifconfig
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
========================================= Matched: ifconfig =========================================
net-tools.x86_64 : Basic networking tools
yum search 搜索可以用于确定某个软件在哪个相关包当中。此例子可以确定“ifconfig”命令需要安装“net-tools”包。
~ yum info 包名
~ yum info samba
# 查询 samba 软件包的信息
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
Available Packages # 还没有安装
Name : samba # 包名
Arch : x86_64 # 适合的硬件平台
Version : 3.6.23 # 版本
Release : 51.el6 # 发布版本
Size : 5.1 M # 大小
Repo : CentOS-ISO # 在光盘上
...省略部分输出...
~ yum install -y 包名
选项:
install 安装
-y 自动回答yes,如果不加 -y,那么每个安装的软件都需要手工回答 yes
# 例如
~ yum install -y gcc
# 使用 yum 自动安装 gcc
~ yum update -y 包名
# 升级指定的软件包
选项:
update:升级
-y :自动回答 yes
注意:在进行升级操作时,yum源服务器中软件包的版本要比本机安装的软件包的版本高。
~ yum update -y
# 升级本机所有软件包
这条命令会升级系统中所有的软件包。不过我们的生产服务器是稳定优先的,所以这种全系统升级的情况并不多见。包括升级内核。
再次强调一下,除非你确定卸载的软件的依赖包不会对系统产生影响,否则不要执行 yum的卸载,因为很有可能在卸载软件包的同时卸载的依赖包也是重要的系统文件,这就有可能导致系统崩溃。卸载命令如下:
~ yum remove 包名
# 卸载指定的软件包
# 例如
~ yum remove -y samba
# 卸载 samba 软件包
~ yum grouplist
# 列出所有可用的软件组列表
~ yum groupinfo 软件组名
# 列出软件组中包含的软件
# 例如:
~ yum groupinfo "Web Server"
# 查询软件组"Web Server"中包含的软件
# CentOS6.3之前的版本是不支持中文
~ yum groupinstall 软件组名
# 安装指定软件组,组名可以由 grouplist 查询出来
# 例如:
~ yum groupinstall -y "Web Server"
# 安装网页服务软件组
~ yum groupremove -y 软件组名
# 卸载指定软件组
rpm包是光盘中直接包含的,所以不需要用户单独下载。而源码包是通过官方网站下载的,如果需要使用,是需要单独下载的。
原因:RPM包安装和源码安装的安装路径各不相同。答案是可以,因为两种安装方法安装的Apache,安装位置是不一样的,例如:
# RPM包:不建议指定安装位置的,建议安装在默认位置(RPM包安装的服务有标准卸载命令,不怕文件到处安装)
配置文件:/etc/httpd/conf/httpd.conf
网页位置:/var/www/html/
日志位置:/var/log/httpd/
启动方法:1)service httpd restart
2)/etc/rc.d/init.d/httpd restart
# 源码包:必须指定安装位置(源码包没有安装数据库,没有删除命令)
配置文件:/usr/local/apache2/conf/httpd.conf
网页文件:/usr/local/apache2/htdocs/
日志文件:/usr/local/apache2/logs/
启动方法:/usr/local/apache2/bin/apachectl start
当然不会啊,因为系统中只有一个80端口,所以你只能启动一个Apache,装多个只能浪费资源。我们建议安装源码包的 Apache。
小总结:
服务是否可以修改端口:
我们来解释一下源码包安装的具体步骤。
(1)下载软件包。
(2)解压缩。
(3)进入解压目录。
(4)./configure 编译前准备。
这一步主要有三个作用:
需要注意的是,configure不是系统命令,而是源码包软件自带的一个脚本程序,所以必须采用“./configure”方式执行(“./”代表在当前目录下。./是执行可执行程序的意思。shell脚本也可以直接这么用)。

(5)make 编译
make 会调用gcc编译器,并读取 Makefile 文件中的信息进行系统软件编译。编译的目的就是把源码程序转变为能被Linux 识别的可执行文件,这些可执行文件保存在当前目录下。编译过程较为耗时,需要有足够的耐心。
(6)make clean 清空编译内容(非必需步骤)
如果在“./configure”或“make”编译中报错,那么我们在重新执行命令前一定要记得执行make clean命令,它会清空Makefile文件或编译产生的“.o”头文件。
(7)make install 编译安装
这才是真正的安装过程,一般会写清楚程序的安装位置。如果忘记指定安装目录,则可以把这个命令的执行过程保存下来,以备将来删除使用。
小总结:
configure 和 make 是都不会硬盘写入任何数据的,只要以上两条命令有任何的报错,则就可以使用 make clean 清空编译内容。
make install 会向硬盘写入数据。
源码包和 RPM 包的管理方法尽量不要放在一块。
源码包:
源码包报错:
1)安装过程必须停止
2)是否出现 no、warning、error 关键字
范例:
# 启动Apache2
~ /usr/local/apache2/bin/apachectl start
~ ps -aux | grep apache2
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root 52603 0.0 0.1 35484 2172 ? Ss 11:45 0:00 /usr/local/apache2/bin/httpd -k start
daemon 52604 0.0 0.0 35484 1572 ? S 11:45 0:00 /usr/local/apache2/bin/httpd -k start
daemon 52605 0.0 0.0 35484 1572 ? S 11:45 0:00 /usr/local/apache2/bin/httpd -k start
daemon 52606 0.0 0.0 35484 1572 ? S 11:45 0:00 /usr/local/apache2/bin/httpd -k start
daemon 52607 0.0 0.0 35484 1572 ? S 11:45 0:00 /usr/local/apache2/bin/httpd -k start
daemon 52608 0.0 0.0 35484 1572 ? S 11:45 0:00 /usr/local/apache2/bin/httpd -k start
root 52622 0.0 0.0 103324 852 pts/1 S+ 11:48 0:00 grep --color=auto apache2
~ curl localhost
<html><body><h1>It works!</h1></body></html>

源码包没有删除命令,如果需要删除,直接删除安装目录即可。
~ diff 选项 old new
# 比较 old 和 new 文件的不同
# 选项
-a 将任何文档当做文本文档处理
-b 忽略空格造成的不同
-B 忽略空白行造成的不同
-I 忽略大小写造成的不同
-N 当比较两个目录时,如果某个文件只在一个目录中,则在另一个目录中视作空文件
-r 当比较目录时,递归比较子目录
-u 使用同一的输出格式
举例:
~ mkdir -pv test
# 建立测试目录
~ cd test
# 进入测试目录
~ cat > old.txt <<EOF
our
school
is
kubesphere
EOF
# 文件 old.txt,为了一会输出便于比较,每行分开
~ cat > new.txt <<EOF
our
school
is
kubesphere
in
Shenzhen
EOF
比较下两个文件的不同,并生成补工文件“txt.patch”,命令如下:
~ diff -Naur /root/test/old.txt /root/test/new.txt
~ diff -Naur /root/test/old.txt /root/test/new.txt > txt.patch
# 比较两个文件的同步,同时生成 txt.patch 补丁文件
--- /root/test/old.txt 2022-08-04 11:59:55.259294777 +0800
+++ /root/test/new.txt 2022-08-04 12:00:09.229909280 +0800
@@ -2,3 +2,5 @@
school
is
kubesphere
+in
+Shenzhen
# 查看下这个文件
~ vi txt.patch
--- /root/test/old.txt 2022-08-04 11:59:55.259294777 +0800
# 前一个文件
+++ /root/test/new.txt 2022-08-04 12:00:09.229909280 +0800
# 后一个文件
@@ -2,3 +2,5 @@
school
is
kubesphere
+in
+Shenzhen
#后一个文件比前一个文件多两行(+表示)
~ patch -pn < 补丁文件
# 按照补丁文件就行更新
选项:
-pn :n为数字。代表按照补丁文件中的路径,指定更新文件的位置
“-pn”不好理解,我们说明下。补丁文件是要打入旧文件的,但是你当前所在的目录和补丁文件中的记录的目录是不一定匹配的,所以就需要“-pn”来同步两个目录。
比如我当前是在“/root/test”目录中(我要打补丁的旧文件就在当前目录下),补丁文件中记录的文件目录为“/root/test/old.txt”,这时如果写入“-p1”(在补丁文件目录中取消一级目录)那么补丁文件就会打入“/root/test/root/test/old.txt”文件中,这显然是不对的。那如果写入的是“-p2”(在补丁文件目录中取消二级目录)那么补丁文件打入的就是“/root/test/test/old.txt”,这显然也不对。如果写入的是“-p3”(在补丁文件目录中取消三级目录)那么补丁文件就是打入的“/root/test/old.txt”,我们的old.txt文件就在这个目录下,所以就应该是“-p3”。
那么我们更新下“old.txt”文件,命令如下:
~ patch -p3 < txt.patch
patching file old.txt
# 给 old.txt 文件打入补丁
~ cat old.txt
# 查看以下 old.txt 的内容
our
school
is
kubesphere
in
Shenzhen
# 多出来了 in Shenzhen 两行
脚本程序包并不多见,所以在软件包分类中并没有把它列为一类。它更加类似于Windows下的程序安装,有一个可执行的安装程序,只要运行安装程序,然后进行简单的功能定制选择(比如指定安装目录等),就可以安装成功,只不过是在字符界面下完成的。
目前常见的脚本程序以各类硬件的驱动居多,我们需要学习一下这类软件的安装方式,以备将来不时之需。
我们来看看脚本程序如何安装和使用。安装一个叫作 Webmin的工具软件,Webmin是一个基于Web的系统管理界面。借助任何支持表格和表单的浏览器(和file Manager模块所需要的Java),你就可以设置用户账号、apache、DNS、文件共享等。Webmin包括一个简单的Web服务器和许多CGI程序,这些程序可以直接修改系统文件,比如 /etc/inetd.conf 和 /etc/passwd。Web服务器和所有的 CGI程序 都是用 Perl 5 编写的,没有使用任何非标准 Perl 模块。也就是说,Webmin是一个用 Perl 语言写的、可以通过浏览器管理 Linux 的软件。
Webmin 本质就是使用 Web 浏览器来管理 Linux 系统的软件。
首先下载Webmin软件,地址为 http://sourceforge.net/projects/webadmin/files/webmin/,这里下载的是 webmin-1.610.tar.gz。

接下来解压缩软件,命令如下:
wget --no-check-certificate https://sourceforge.net/projects/webadmin/files/webmin/1.610/webmin-1.610.tar.gz/download
tar -zxvf webmin-1.610.tar.gz
进入解压目录,命令如下:
cd webmin-1.610
执行安装程序 setup.sh 并指定功能选项,命令如下:
~ ./setup.sh
***********************************************************************
* Welcome to the Webmin setup script, version 1.610 *
***********************************************************************
Webmin is a web-based interface that allows Unix-like operating
systems and common Unix services to be easily administered.
Installing Webmin in /root/webmin-1.610 ...
***********************************************************************
Webmin uses separate directories for configuration files and log files.
Unless you want to run multiple versions of Webmin at the same time
you can just accept the defaults.
Config file directory [/etc/webmin]:
# 选择安装位置,默认安装在 /etc/webmin 目录下,如果安装到默认位置,则直接回车
Log file directory [/var/webmin]:
# 日志文件保存位置,直接回车,选择默认位置
***********************************************************************
Webmin is written entirely in Perl. Please enter the full path to the
Perl 5 interpreter on your system.
Full path to perl (default /usr/bin/perl):
# 指定 Perl 语言的安装位置,直接回车,选择默认位置,Perl 默认就安装在这里
Testing Perl ...
Perl seems to be installed ok
***********************************************************************
Operating system name: CentOS Linux
Operating system version: 6.10
***********************************************************************
Webmin uses its own password protected web server to provide access
to the administration programs. The setup script needs to know :
- What port to run the web server on. There must not be another
web server already using this port.
- The login name required to access the web server.
- The password required to access the web server.
- If the webserver should use SSL (if your system supports it).
- Whether to start webmin at boot time.
Web server port (default 10000):
# 指定Webmin 监听的端口,直接回车,默认选定10000
Login name (default admin):
# 输入登录Webmin 的用户名
Login password:
Password again:
# 输入登录密码
The Perl SSLeay library is not installed. SSL not available.
# Apache 默认没有启动SSL功能,所以SSL没有被激活
Start Webmin at boot time (y/n):y
...省略部分内容...
Attempting to start Webmin mini web server..
Starting Webmin server in /root/webmin-1.610
Pre-loaded WebminCore
..done
***********************************************************************
Webmin has been installed and started successfully. Use your web
browser to go to
http://10.0.0.40:10000/
and login with the name and password you entered previously.

个人电脑 和 服务器级别的用户管理和用户权限管理是不一样的。Windows 的权限是绑定在用户组上的,用户拥有什么权限,不取决于该用户,而是取决于该用户所属于的用户组。默认Windows 添加的新用户都是属于 User 组中。
权限分割 主要规范内部人员。
系统权限 ROOT 给了运维同学,ROOT 权限给运维主管,普通权限给普通运维。MySQL 给了 DBA 普通权限进行处理。在 数据库 ROOT 权限是 DBA 使用。
root❌0:0:root:/root:/bin/bash
第一列:用户名
第二列:密码位
第三列:用户ID
0 超级用户UID。如果用户UID为0,代表这个账号是管理员账号。那Linux中如何把普通用户升级成为管理员呢?就是把其他用户的UID修改为0就可以了,这点和Windows是不同的。不过不建议建立多个管理员账号。
1-499 系统用户(伪用户)UID。这些UID账号是系统保留给系统用户的UID,也就是说UID是1-499范围内的用户是不能登录系统的,而是用来运行系统或服务的。其中 1-99是系统保留的账号,系统自动创建。100-499是预留给用户创建系统账号的。
500-65535普通用户UID。建立的普通用户UID 从500开始,最大到65535。这些用户足够使用了,但是如果不够也不用害怕,2.6.x内核以后的Linux系统用户UID已经可以支持 2^32 这么多了。
CentOS 7 之后,系统用户是在 1-999 系统用户(伪用户)UID。理论上每个服务都需要有各自服务的伪用户。
第四列:组ID、GID添加用户时,如果不指定用户所属的初始组,那么会建立和用户名相同的组
第五列:用户说明
第六列:用户家目录 ~
第七列:登录Shell /bin/bash
如何把普通用户变成超级用户:把用户 UID 改为 0。
RHEL 5 之前的用户密码加密算法是 MD5,RHEL 6 之后的用户密码加密算法是 SHA512
root: 6 6 6SckntYMN$xhj0yVZ8U4rTQDkZQnrxd0aU42iXFjMu9KIbpsuyG2WRBVI6zTBTcvCxua4BveAL0qvj7IuhDr2tFhBFGCXZ6/:19188:0:99999:7:::
第一列:用户名
第二列:加密密码
我们也可以在密码前人为的加入“!”或“*”改变加密值让密码(暂时失效)-,使这个用户无法登陆,达到暂时禁止用户登录的效果。
注意所有伪用户的密码都是“!!”或“*”,代表没有密码是不能登录的。当然我新创建的用户如果不设定密码,它的密码项也是“!!”,代表这个用户没有密码,不能登录
第三列:密码最近更改时间,1970年1月1日作为标准时间
时间截转日期
~ date -d "1970-01-01 15775 days"
Mon Mar 11 00:00:00 CST 2013
~ date -d "1970-01-01 19188 days"
Fri Jul 15 00:00:00 CST 2022
日期转时间戳
~ echo $(($(date --date="2013/03/11" +%s)/86400+1))
15775
~ echo $(($(date --date="2022/8/11" +%s)/86400+1))
19215
~ getent shadow user1
user1:$6$GuICMum6$giOwTp2nkXWvf5mxntP6tP/teKHckB1mA491lmX.GokT8ufWRKFN9rVpsYr.wZG31Ww4Xyza6jXMOwIBQJElo1:19215:0:99999:7:::
第四列:两次密码的修改间隔时间(和第3字段相比,不推荐修改)
第五例:密码有效期(和第3字段相比,99999 相当于是永久有效)
第六列:密码修改到期前的警告天数(和第5字段相比)
第七列:密码过期后的宽限天数(和第5字段相比)
第八列:密码失效时间
这里同样要写时间戳,也就是用1970年1月1日进行时间换算。如果超过了失效时间,就算密码没有过期,用户也就失效无法使用了。
第九列:保留
root❌0:root
第一列:组名
第二列:组密码位,并不推荐在用户组上设置密码。
第三列:GID,组ID号
第四列:此组中支持的其他用户,附加组是此组的用户
初始组:每个用户初始组只能有一个,初始组只能有一个,一般都是和用户名相同的组作为初始组
附加组:每个用户可以属于多个附加组。要把用户加入组,都是加入附加组
如果我给用户组设定了组管理员,并给该用户组设定了组密码,组密码就保存在这个文件当中。组管理员就可以利用这个密码管理这个用户组了。
默认普通用户的家目录是在 /home 下创建同名的家目录
这个邮箱在/var/spool/mail目录当中,例如lamp用户的邮箱就是/var/spool/mail/lamp文件
/etc/skel 目录是用来存放新用户配置文件的目录,当我们添加新用户的时候,这个目录下的所有文件会自动被复制到新添加的用户的家目录下。
这个目录下的所有文件都是隐藏文件(以.点开头的文件)。
通过修改、添加、删除/etc/skel目录下的文件,我们可为新创建的用户提供统一的、标准的、初始化用户环境。
/etc/default/useradd 定义创建新用户的适合,从哪里 COPY 环境变量文件,默认执行 Shell 的方式等等
# useradd defaults file
GROUP=100 #用户默认组
HOME=/home #用户家目录
INACTIVE=-1 #密码过期宽限天数(shadow文件 7 字段)
EXPIRE= #密码失效时间(shadow文件 8 字段)
SHELL=/bin/bash #默认Shell类型
SKEL=/etc/skel #模板目录
CREATE_MAIL_SPOOL=yes #是否建立邮箱
手工删除用户实验:手工删除,如果可以正常建立用户,证明用户删除干净
DELUSER="user1"
sed -i.bak -r "/${DELUSER}/d" /etc/passwd
sed -i.bak -r "/${DELUSER}/d" /etc/shadow
sed -i.bak -r "/${DELUSER}/d" /etc/group
sed -i.bak -r "/${DELUSER}/d" /etc/gshadow
rm -rf /home/${DELUSER} ; rm -rf /var/spool/mail/${DELUSER}
~ id user1
id: user1: no such user
# userdel -r user1
useradd 选项 用户名
选项
例如:
~ groupadd lamp1
#先手工添加lamp1用户组,因为我一会要把lamp1用户的初始组指定过来,如果不事先建立,会报错用户组不存在
~ useradd -u 550 -g lamp1 -G root -d /home/lamp1 -c "test user" -s /bin/bash lamp1
#建立用户lamp1的同时指定了UID(550),初始组(lamp1),附加组(root),家目录(/home/lampl),
#用户说明(test user)和用户登录shell (/bin/bash)
~ grep "lamp1" /etc/passwd /etc/shadow /etc/group
/etc/passwd:lamp1:x:550:1002:test user:/home/lamp1:/bin/bash
#用户的UID、初始组、用户说明、家目录和登录shell都和命令手工指定的一致
/etc/shadow:lamp1:!!:19215:0:99999:7:::
#lamp1用户还没有设定密码
/etc/group:root:x:0:lamp1
#lamp1用户加入了root组, root组是lamp1用户的附加组
/etc/group:lamp1:x:1002:
#GID502的组是lamp1组
~ ls -ld /home/lamp1/
drwx------ 3 lamp1 lamp1 95 Aug 11 11:12 /home/lamp1/
# 家目录也建立了,不需要手工建立家目录
范例:-g 和 -G 的区别
~ groupadd t1 ; groupadd t2
~ useradd -g t1 u1 ; useradd -G t2 u2
~ id u1
uid=1001(u1) gid=1003(t1) groups=1003(t1)
~ id u2
uid=1002(u2) gid=1005(u2) groups=1005(u2),1004(t2)
~ grep "u2" /etc/passwd
u2:x:1002:1005::/home/u2:/bin/bash
~ grep "t2" /etc/group
t2:x:1004:u2
useradd 添加用户时参考的默认值文件主要有两个,分别是 /etc/default/useradd 和 /etc/login. defs。
1)/etc/default/useradd
~ vim /etc/default/useradd
# useradd defaults file
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
挨个解释下:
这个选项是建立用户的默认组,也就是说添加每个用户时,用户的初始组就是GID为100的这个用户组。目前我们采用的机制私有用户组机制。
这个选项是用户的家目录的默认位置,所以所有的新建用户的家目录默认都在/home/下。
这个选项就是密码过期后的宽限天数,也就是 /etc/shadow 文件的第七个字段。如果是天数,比如10代表密码过期后10天后失效;如果是0,代表密码过期后立即失效;如果是-1,则代表密码永远不会失效。这里默认值是-1,所以所有新建立的用户密码都不会失效。
推荐改为 0 ,代表密码过期后立刻失效。
这个选项是密码失效时间,也就是 /etc/shadow 文件的第八个字段。也就说用户到达这个日期后就会直接失效。当然这里也是使用时间戳来表示日期的。默认值是空,所以所有新建用户没有失效时间,永久有效。
这个选项是用户的默认shell的。/bin/bash 是 Linux 的标志 shell,所以所有新建立的用户默认都具备 shell 赋予的权限。
这个选项就是定义用户的模板目录的位置,/etc/skel/目录中的文件都会复制到新建用户的家目录当中。
这个选项定义是否给新建用户建立邮箱,默认是创建,也就是说所有的新建用户系统都会新建一个邮箱,放在 /var/spool/mail/ 下和用户名相同。
2)/etc/login.defs
~ grep -Ev "^#" /etc/login.defs
# vim /etc/login.defs
#这个文件有些注释,把注释删除掉,文件内容就变成下面这个样子
MAIL_DIR /var/spool/mail
PASS_MAX_DAYS 99999
PASS_MIN_DAYS 0
PASS_MIN_LEN 5
PASS_WARN_AGE 7
UID_MIN 1000
UID_MAX 60000
SYS_UID_MIN 201
SYS_UID_MAX 999
GID_MIN 1000
GID_MAX 60000
SYS_GID_MIN 201
SYS_GID_MAX 999
CREATE_HOME yes
UMASK 077
USERGROUPS_ENAB yes
ENCRYPT_METHOD SHA512
我们一行一行解释下文件内容:
这行指定了新建用户的默认邮箱位置。比如lamp用户的邮箱是就是/var/spool/mail/lamp。
这行指定的是密码的有效期,也就是/etc/shadow文件的第五字段。代表多少天之后必须修改密码,默认值是99999。推荐进行修改该参数的值,尽量设置的小一些。
这行指定的是两次密码的修改间隔时间,也就是/etc/shadow文件的第四字段。代表第一次修改密码之后,几天后才能再次修改密码。默认值是0。
这行代表密码的最小长度,默认不小于5位。但是我们现在用户登录时验证已经被PAM模块取代,所以这个选项并不生效。
这行代表密码修改到期前的警告天数,也就是/etc/shadow文件的第六字段。代表密码到底有效期前多少天开始讲行警告提醒,默认值是7天。
这两行代表创建用户时,最小UID和最大的UID的范围。我们2.6.x内核开始,Linux用户的UID最大可以支持2这么多,但是真正使用时最大范围是60000。还要注意如果我手工指定了一个用户的UID是550,那么下一个创建的用户的UID就会从551开始,哪怕500-549之间的UID没有使用(小于500的UID是给伪用户预留的)。
这两行指定了GID的最小值和最大值之间的范围。
这行指定建立用户时是否自动建立用户的家目录,默认是建立
这行指定的是建立的用户家目录的默认权限,因为umask值是 077,所以新建的用户家目录的权限是700,umask的具体作用和修改方法我们可以参考下一章权限设定章节。
这行指定的是使用命令 userdel 删除用户时,是否删除用户的初始组,默认是删除。
这行指定Linux用户的密码使用 SHA512 散列模式加密,这是新的密码加密模式,原先的Linux只能用 DES 或 MD5 方式加密
超级用户可以设置其他普通用户以及自身的密码;普通用户只能设置自身的密码。
~ passwd [选项] 用户名
选项:
-l:暂时锁定用户。仅root用户可用
-u:解锁用户。仅root用户可用
--stdin:可以将通过管道符输出的数据作为用户的密码。主要在批量添加用户时使用
~ passwd
#passwd 直接回车代表修改当前用户的密码
也可以使用字符串作为密码:
~ echo "123" | passwd --stdin lamp
# 更改用户 lamp 的密码
可以通过命令,把密码修改日志归零(shadow 第3字段)。这样用户一登陆就要修改密码,例如:
chage -d 0 lamp
# 登录强制修改密码
chage -d 0 <user-name>
passwd -e <user-name>
usermod命令是修改已经添加的用户的信息的,命令如下:
~ usermod [选项] 用户名
选项:
-u UID :修改用户的UID
-d 家目录:修改用户的家目录。家目录必须写绝对路径
-c 用户说明:修改用户的说明信息,就是/etc/passwd文件的第五个字段
-g 组名 :修改用户的初始组,就是/etc/passwd 文件的第四个字段
-G 组名 :修改用户的附加组,其实就是把用户加入其他用户组(usermod 常用的选项)
-s shell:修改用户的登录Shell。默认是/bin/bash
-e 日期 :修改用户的失效日期,格式为“YYYY-MM-DD”。也就是/etc/shadow文件的第八个字段
-L :临时锁定用户(Lock)
-U :解锁用户(Unlock)
Linux 系统中,不建议修改用户名;原因:Windows 更加的智能,修改用户名之后,会自动的将日志中该用户名也进行相关的修改操作,而 Linux 系统中的用户名修改后,初始组以及对应的信息均不会进行修改。
那用户可以修改用户名吗?当然可以:
~ usermod -l 新名 旧名
# 改名
但是真不建议改名,这样及其容易把管理员自己搞晕菜,建议删除旧用户,再建立新用户!
~ userdel [-r] 用户名
选项:
-r:在删除用户的同时删除用户的家目录
-f:强制删除
范例:
userdel -r user2
su命令可以切换成不同的用户身份,命令格式如下:
~ su [选项] 用户名
选项:
- :选项只使用“-”代表连带用户的环境变量一起切换
-c 命令:仅执行一次命令,而不切换用户身份
“_”不能省略,它代表切换用户身份时,用户的环境变量也要切换成新用户的环境变量。
~ su - u1
[u1@zdevops-master ~]$ pwd
/home/u1
# 执行一次命令,而不切换用户身份
[u1@zdevops-master ~]$ su - root -c ls /root
Password:
anaconda-ks.cfg reset.sh
添加用户组的命令是groupadd,命令格式如下:
~ groupadd [选项] 组名
选项:
-g GID:指定组ID
添加用户组的命令比较简单,举个例子:
~ groupadd group1
#添加group1组
~ grep "group1" /etc/group
group1:x:1005:
groupdel命令用于删除用户组,命令格式如下:
~ groupdel 组名
#例子:
~ groupdel testgrp
#删除 testgrp 组
不过大家要注意,要删除的组不能是其他用户的初始组,也就是说这个组中没有初始用户才可以删除。如果组中有附加用户,则删除组时不受影响。
删除用户组时,一定要确保该用户组内不能含有其他用户使用该用户组。删除用户组的时候,必须确保该用户组没有初始用户。否则是无法删除的。
其实 gpasswd命令是用来设定组密码并指定组管理员的,不过我们在前面已经说了,组密码和组管理员功能很少使用,而且完全可以被sudo命令取代,所以 gpasswd命令现在主要用于把用户添加进组或从组中删除。命令格式如下:
~ gpasswd [选项] 组名
选项:
-a 用户名:把用户加入组
-d 用户名:把用户从组中删除
举个例子:
~ groupadd grouptest
#添加组 grouptest
~ gpasswd -a lamp grouptest
Adding user lamp to group grouptest
#把用户lamp加入到 grouptest
~ grep "lamp" /etc/group
grouptest:x:1006:lamp
lamp:x:1007:
#查看一下,lamp用户已经作为附加用户加入到grouptest用户组
~ gpasswd -d lamp grouptest
Removing user lamp from group grouptest
#把用户lamp从组中删除
~ grep "lamp" /etc/group
lamp:x:1007:
#组中没有lamp用户了
大家注意,也可以使用usermod命令把用户加入某个组,不过usermod命令的操作对象是用户,命令是“usermod -G grouptest lamp”,把用户名作为参数放在最后;而 gpasswd 命令的操作对象是组,命令是“gpasswd -a lamp grouptest”,把组名作为参数放在最后。
我们说过,每个用户可以属于一个初始组(用户是这个组的初始用户),也可以属于多个附加组(用户是这个组的附加用户)。既然用户可以属于这么多用户组,那么用户在创建文件后,默认生效的组身份是哪个呢?当然是初始用户组的组身份生效了,因为初始组是用户一旦登录就直接获得的组身份。也就是说,用户在创建文件后,文件的属组是用户的初始组,因为用户的有效组默认是初始组。既然用户属于多个用户组,那么能不能改变用户的有效组呢﹖使用命令newgrp就可以切换用户的有效组。命令格式如下:
~ newgrp 组名
#前提是该用户需要在修改的用户组内(附加组)
举个例子,我们已经有了普通用户user1,默认会建立user1用户组,user1组是user1用户的初始组。我们再把user1用户加入group1组,那么group1组就是user1用户的附加组。当user1 用户创建文件test1时,test1文件的属组是user1组,因为userl组是user1用户的有效组。通过newgrp 命令就可以把user1用户的有效组变成 group1组,当 user1用户创建文件test2 时,就会发现 test2文件的属组就是group1组。命令如下:
➜ ~ useradd -c "Test User1" user1 ; useradd -c "Test User2" user2
#添加测试用户
➜ ~ groupadd group1
#添加组group1
➜ ~ gpasswd -a user1 group1
#把user1用户加入group1组
Adding user user1 to group group1
➜ ~ grep "user1" /etc/group
group1:x:1049:user1
user1:x:1050:
#user1用户即属于user1,也属于group1组
➜ ~ su - user1
#切换成user1身份,超级用户切换成普通用户不用密码
[user1@kubesphere-docker ~]$ touch test1
[user1@kubesphere-docker ~]$ ls -l test1
-rw-rw-r-- 1 user1 user1 0 Aug 11 14:55 test1
#test1文件的默认属组是 user1 组
[user1@kubesphere-docker ~]$ newgrp group1
#切换user1用户的有效组为 group1 组,会新开启一个Bash,用户组为 newgrp 的组
[user1@kubesphere-docker ~]$ touch test2
[user1@kubesphere-docker ~]$ ls -l
total 0
-rw-rw-r-- 1 user1 user1 0 Aug 11 14:55 test1
-rw-r--r-- 1 user1 group1 0 Aug 11 14:56 test2
#test2文件的默认属组是 group1 组
通过这个例子明白有效组的作用了吗?其实就是当用户属于多个组时,在创建文件时哪个组身份生效。使用newgrp命令可以在多个组身份之间切换。
扩展
~ id user2
uid=502(user2) gid=502(user2) groups=502(user2),501(user1)
#用户ID,用户组ID,用户组:初始组,附加组
~ su - user2
$ whoami
user2
$ pwd
/home/user2
#新建测试目录
~ mkdir -pv /www
#创建新增用户
~ useradd -c "Test User" sc
~ echo "123456" | passwd --stdin sc &> /dev/null
~ groupadd tg
~ for u in user{1,2} ; do useradd -c "Test User" $u ; echo "123456" | passwd --stdin $u &> /dev/null ; done
~ gpasswd -a user1 tg ; gpasswd -a user2 tg
~ id user1
uid=501(user1) gid=501(user1) groups=501(user1),504(tg)
~ id user2
uid=502(user2) gid=502(user2) groups=502(user2),504(tg)
~ chown sc:tg /www/
~ ls -ld /www/
drwxr-xr-x 2 sc tg 6 Aug 11 15:57 /www/
~ chmod 770 /www/
~ ls -ld /www/
drwxrwx--- 2 sc tg 6 Aug 11 15:57 /www/
Windows 系统中的权限管理也是依旧复杂,结合了域控制之后,权限管理会更加复杂。
传统的所有者,所属组,其他人的三种身份权限显得不够,需要使用ACL权限来解决用户对文件身份不足的问题。
ACL 主要是用于解决用户对文件身份不足的问题。
在普通权限中,用户对文件只有三种身份,就是属主、属组和其他人;每种用户身份拥有读(read)、写(write)和执行(execute)三种权限。但是在实际工作中,这三种身份实在是不够用,我们举个例子来看看。

根目录中有一个 /project 目录,这是班级的项目目录。班级中的每个学员都可以访问和修改这个目录,老师也需要对这个目录拥有访问和修改权限,其他班级的学员当然不能访问这个目录。需要怎么规划这个目录的权限呢?应该这样:老师使用 root 用户,作为这个目录的属主,权限为 rwx;班级所有的学员都加入 tgroup 组,使 tgroup 组作为 /project 目录的属组,权限是 rwx;其他人的权限设定为 0。这样这个目录的权限就可以符合我们的项目开发要求了。
有一天,班里来了一位试听的学员 st,她必须能够访问 /project 目录,所以必须对这个目录拥有 r 和 x 权限;但是她又没有学习过以前的课程,所以不能赋予她 w 权限,怕她改错了目录中的内容,所以学员 st 的权限就是 r-x。可是如何分配她的身份呢?变为属主?当然不行,要不 root 该放哪里?加入 tgroup 组?也不行,因为 tgroup 组的权限是 rwx,而我们要求学员 st 的权限是 r-x。如果把其他人的权限改为 r-x 呢?这样一来,其他班级的所有学员都可以访问 /project 目录了。
当出现这种情况时,普通权限中的三种身份就不够用了。ACL 权限就是为了解决这个问题的。在使用 ACL 权限给用户 st 赋予权限时,st 既不是 /project 目录的属主,也不是属组,仅仅赋予用户 st 针对此目录的 r-x 权限。这有些类似于 Windows 系统中分配权限的方式,单独指定用户并单独分配权限,这样就解决了用户身份不足的问题。
ACL是Access Control List(访问控制列表)的缩写,不过在Linux系统中,ACL用于设定用户针对文件的权限,而不是在交换路由器中用来控制数据访问的功能(类似于防火墙)。
在 CentOS 6.x 系统中 ACL 权限默认是开启的,不需要手工开启。不过,如果你的操作系统不是 CentOS 6.x,那该如何查看 ACL 权限是否开启了呢?可以这样查看:
mount | grep acl
#使用mount命令可以看到系统中已经挂载的分区,但是并没有看到ACL权限的设置
#dump2fs 命令是查询指定分区详细文件系统信息的命令
#选项:
-h:仅显示超级块中的信息,而不是显示磁盘块组的详细信息
~ dumpe2fs /dev/sda1
...省略部分输出...
Default mount options: user_xattr acl
...省略部分输出...
#ACL权限是绑定在分区上的
如果没有开启,手工开启分区的 ACL 权限:
mount -o remount,acl /
#重新挂载根分区,并挂载加入 ACL 权限
使用 mount 命令重新挂载,并加入 ACL 权限。不过使用此命令是临时生效的。要想永久生效,需要修改 /etc/fstab 文件,命令如下:
~ vim /etc/fstab
UUID=c2ca6f57-b15c-43ea-bca0-f239083d8bd2 /ext4 defaults, acl 1 1
#加入ACL权限
[root@localhost ~]# mount -o remount /
#重新挂载文件系统或重启系统,使修改生效
在你需要开启 ACL 权限的分区行上(也就是说 ACL 权限针对的是分区),手工在 defaults 后面加入",acl"即可永久在此分区中开启 ACL 权限。
注意:一旦拥有的ACL权限,那么 ls -l 查看的权限就会有不准确的情况。
ACL 权限,一旦递归之后,不可避免的出现权限溢出。例如:赋予执行之后,对目录来说就是是否可以进入该目录,对文件来说就是可以运行该文件。
尽量使用标准权限,能不使用ACL权限就尽量不要使用。
getfacl 文件名 查询文件的ACL权限
setfacl [选项] 文件名 设定 ACL权限
setfacl -m u:用户名:权限 文件名
setfacl -m g:组名:权限 文件名
范例:
setfacl -m u:aa:rwx /test
#给test目录赋予 aa 是读写执行的ACL权限
setfacl -m u:cc:rw -R soft/
#赋予递归ACL权限,只能赋予目录
-R:递归
setfacl -m d:u:aa:rwx -R
#ACL默认权限。注意:默认权限只会赋予目录
注意:如果给目录赋予acl权限,两条命令都要输入
递归与默认的区别:
#只对已经存在的文件生效
setfacl -m u:cc:rx -R soft/
#只对以后新建的文件生效
setfacl -m d:u:cc:rx -R soft/
范例:
~ setfacl -m d:u:st:r-x /www/
~ getfacl /www/
getfacl: Removing leading '/' from absolute path names
# file: www/
# owner: sc
# group: tg
user::rwx
user:st:r-x
group::rwx
mask::rwx
other::---
default:user::rwx
default:user:st:r-x
default:group::rwx
default:mask::rwx
default:other::---
~ touch /www/def
~ getfacl /www/def
# file: def
# owner: root
# group: root
user::rw-
user:st:r-x #effective:r--
group::rwx #effective:rw-
mask::rw-
other::---
mask 是用来指定最大有效权限的。mask 的默认权限是 rwx,如果我给 st 用户赋予了 r-x 的 ACL 权限,mj 需要和 mask 的 rwx 权限"相与"才能得到 st 的真正权限,也就是 r-x "相与"rwxtj 出的值是 r-x,所以 st 用户拥有 r-x 权限。
如果把 mask 的权限改为 r–,和 st 用户的权限相与,也就是 r–"相与"r-x 得出的值是 r–,st 用户的权限就会变为只读。大家可以这么理解:用户和用户组所设定的权限必须在 mask 权限设定的范围之内才能生效,mask权限就是最大有效权限。
不过我们一般不更改 mask 权限,只要给予 mask 最大权限 rwx,那么任何权限和 mask 权限相与,得出的值都是权限本身。也就是说,我们通过给用户和用户组直接赋予权限,就可以生效,这样做更直观。
~ setfacl -m m:rx project/
#设定 mask 权限为 r-x,使用"m:权限"格式
~ getfacl project/
# file: project/
# owner: sc
# group: tg
user::rwx
user:st:r-x #effective:r--
group::rwx #effective:rw-
mask::rw-
#mask权限变为了 r-x
other::---
###Mask权限默认即可。因为在每一次用户ACL刷新后,Mask权限值都会随之刷新。
###只有等到用户ACL权限设置完毕后,再最后对Mask权限进行设置
~ setfacl -x u:st /project/
#删除指定用户和用户组的ACL权限
~ setfacl -b /project/
#会输出文件/目录的所有的ACL权限
给普通用户赋予部分管理员权限。Linux sudo命令以系统管理者的身份执行指令,也就是说,经由 sudo 所执行的指令就好像是 root 亲自执行。
使用权限:在 /etc/sudoers 中有出现的使用者。
sudo 赋予的权限越详细,普通用户得到的权限越小
赋予的权限越简单,普通用户得到的权限越大
1 root 身份:
visudo 赋予普通用户权限命令,命令执行后和vi一样使用。(类似于 vim /etc/sudoers)
root ALL=(ALL) ALL
#用户名 被管理主机的地址=(可使用的身份) 授权命令(绝对路径)
%wheel ALL=(ALL) ALL
#%组名 被管理主机的地址=(可使用的身份) 授权命令(绝对路径)
#ALL=(ALL) 第一个ALL代表任意被管理端主机
~ man 5 sudoers
Host_Alias CSNETS = 128.138.243.0, 128.138.204.0/24, 128.138.242.0
jack CSNETS = ALL
用户jack可以在CSNETS别名(网络)中的机器上运行任何命令
128.138.243.0、128.138.204.0 和 128.138.242.0)。这些网络中,只有128.138.204.0
有一个显式的网络掩码 (在CIDR符号中) 表明它是一个 C 类网络。为在CSNETS的其他网络中,本地机器的子网掩码将在匹配时使用。
2 举例
1)举个例子,比如授权用户 user1 可以重启服务器,则由root用户添加如下行:
~ visudo
user1 ALL=/sbin/shutdown -r now
~ sudo -l
Matching Defaults entries for root on this host:
!visiblepw, always_set_home, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC
KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE",
env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY
LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS
_XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User root may run the following commands on this host:
(ALL) ALL
#查看可用的授权
#use1 用户登录
$sudo -l
User user1 may run the following commands on this host:
(root) /sbin/shutdown -r now
2)再举个例子,授权一个用户管理你的Web服务器,不用自己插手是不是很爽,以后修改设置更新网页什么都不用管,一定Happy死了,Look:
首先要分析授权用户管理Apache至少要实现哪些基本授权:
1、可以使用Apache管理脚本
2、可以修改Apache配置文件
3、可以更新网页内容
假设 Apache管理脚本程序为/etc/rc.d/ init.d/httpd 。为满足条件一,用 visudo 进行授权:
~ vim /etc/sudoers
user1 ALL=/etc/rc.d/init.d/httpd reload, /etc/rc.d/init.d/httpd configtest
#user1 192.168.0.156=/etc/rc.d/init.d/httpd reload,/etc/rc.d/init.d/httpd configtest
授权用户user1 可以连接192.168.0.156 上的Apache服务器,通过Apache管理脚本重新读取配置文件让更改的设置生效(reload)和可以检测Apache配置文件语法错误(configtest),但不允许其执行关闭(stop)、重启(restart)等操作。(“\”的意思是一行没有完成,下面的内容和上一行是同一行。)
范例:
$ sudo -l
[sudo] password for user1:
User user1 may run the following commands on this host:
(root) /etc/rc.d/init.d/httpd reload, (root) /etc/rc.d/init.d/httpd configtest
为满足条件二,同样使用 visudo 授权:
~ vim /etc/sudoers
user1 ALL=/etc/rc.d/init.d/httpd reload, /etc/rc.d/init.d/httpd configtest, \
/bin/vi /etc/httpd/conf/httpd.conf
#user1 192.168.0.156=/bin/vi /etc/httpd/conf/httpd.conf
#允许user1 在192.168.0.156上执行/bin/vi /etc/httpd/conf/httpd.conf
$ sudo -l
[sudo] password for user1:
User user1 may run the following commands on this host:
(root) /etc/rc.d/init.d/httpd reload, (root) /etc/rc.d/init.d/httpd configtest, (root)
/bin/vi /etc/httpd/conf/httpd.conf
授权用户user1 可以用root身份使用vi编辑Apache配置文件。
以上两种sudo的设置,要特别注意,很多朋友使用sudo会犯两个错误:第一,授权命令没有细化到选项和参数;第二,认为只能授权管理员执行的命令。
条件三则比较简单,假设网页存放目录为/var/www/html ,则只需要授权userl对此目录具有写权限或者索性更改目录所有者为user1即可。如果需要,还可以设置 user1 可以通过FTP等文件共享服务更新网页。
3)授权aa用户可以添加其他普通用户
aa ALL=/usr/sbin/useradd 赋予aa添加用户权限,命令必须写入绝对路径
aa ALL=/usr/bin/passwd 赋予改密码权限,直接使用该操作会导致用户可以修改root密码
取消对root的密码修改
#! 代表取反的意思
aa ALL=/usr/bin/passwd [A-Za-z0-9]*, !/usr/bin/passwd “”, !/usr/bin/passwd root
aa 身份
sudo /usr/sbin/useradd ee 普通用户使用sudo命令执行超级用户命令
范例:
~ vim /etc/sudoers
user1 ALL=/etc/rc.d/init.d/httpd reload, /etc/rc.d/init.d/httpd configtest, \
/bin/vi /etc/httpd/conf/httpd.conf
user1 ALL=/usr/sbin/useradd, /usr/bin/passwd [A-Za-z0-9]*, !/usr/bin/passwd "", \
!/usr/bin/passwd root
$ sudo -l
User user1 may run the following commands on this host:
(root) /etc/rc.d/init.d/httpd reload, (root) /etc/rc.d/init.d/httpd configtest, (root)
/bin/vi /etc/httpd/conf/httpd.conf
(root) /usr/sbin/useradd, (root) /usr/bin/passwd [A-Za-z0-9]*, (root) !/usr/bin/passwd \"\",
(root) !/usr/bin/passwd root

SetUID、SetGID、StickyBIT,该三个特殊权限也会简称为SUID,SGID,SBIT。是Linux 系统下的三个特殊权限。是Linux 应对特殊情况所准备的特殊权限。主要是用于LInux 的特殊命令,不建议以及不推荐用户手工设置特殊权限。尤其是 SUID。
特殊权限:
1)SetUID 是什么
SetUID的功能可以这样理解:
SetUID 需要满足本身是可执行文件(在所有者上 x 执行权限),其次是其他用户可以拥有该可执行文件的执行权限(x 执行权限)。这样才会使得 SetUID 生效。
2)举例
~ ls -l /etc/passwd
-rw-r--r-- 1 root root 2773 Aug 11 14:54 /etc/passwd
~ ls -l /etc/shadow
---------- 1 root root 2750 Aug 13 11:17 /etc/shadow
因为
~ ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 27856 Apr 1 2020 /usr/bin/passwd
#普通用户是无法指定特定的用户修改密码的
~ passwd user1
passwd: Only root can specify a user name.
~ passwd
Changing password for user user1.
Changing password for user1.
New password: Admin@h3c
Retype new password: Admin@h3c
passwd: all authentication tokens updated successfully.
#这样就可以避免普通用户修改root密码以及其他用户的密码
/usr/bin/passwd 命令拥有特殊权限 SetUID,也就是在属主的权限位的执行权限上是s。可以这样来理解它:当一个具有执行权限的文件设置SetUID 权限后,用户执行这个文件时将以文件所有者的身份执行。/usr/bin/passwd命令具有SetUID 权限,所有者为root (Linux 中的命令默认所有者都是root),也就是说当普通用户使用passwd更改自己密码的时候,那一瞬间突然灵魂附体了,实际是在用 passwd 命令所有者root 的身份在执行passwd命令,root当然可以将密码写入/etc/shadow文件(不要忘记root这个家伙是superman 什么事都可以干),所以普通用户也可以修改 /etc/shadow 文件,命令执行完成后该身份也随之消失。

如果取消SetUID权限,则普通用户就不能修改自己的密码了
~ chmod u-s /usr/bin/passwd
~ ls -l /usr/bin/passwd
-rwxr-xr-x. 1 root root 27856 Apr 1 2020 /usr/bin/passwd
~ passwd
Changing password for user user1.
Changing password for user1.
(current) UNIX password:
New password:
Retype new password:
passwd: Authentication token manipulation error
#修改回来之后,就可以正常修改密码
3)危险的 SetUID
~ chmod u+s /usr/bin/vim
~ ls -l /usr/bin/vim
-rwsr-xr-x 1 root root 2337208 Dec 16 2020 /usr/bin/vim
4)有几点建议:
5)检测 SetUID 的脚本
~ find / -perm -4000 -o -perm -2000 | grep -E "^/usr/(bin|sbin)" > /root/suid.list
#创建模板文件
~ vim suidcheck.sh
#!/bin/bash
find / -perm -4000 -o -perm -2000 | grep -E "^/usr/(bin|sbin)" > /tmp/setuid.check
#搜索系统中所有拥有SUID和SGID的文件,并保存到临时目录中。
for i in $(cat /tmp/setuid.check)
#做循环,每次循环取出临时文件中的文件名
do
grep $i /root/suid.list > /dev/null
#比对这个文件名是否在模板文件中
if [ "$?" != "0" ] ; then
echo "$i isn't in listfile!"
echo "$i isn't in listfile!" >> /root/suid_log_$(date +%F)
#如果文件名不再模板文件中,则报错。并把报错报错到日志中
fi
done
rm -rf /tmp/setuid.check
#删除临时文件
~ chmod u+s /usr/bin/vim
#手工给 ls 加入SUID 权限
~ ./suidcheck.sh
#执行检测脚本
~ cat suid_log_2022-08-13
/usr/bin/ls isn't in listfile!
#报错了,ls不再模板文件中。代表 ls 被修改了SUID权限
1)针对文件的作用
SGID即可以针对文件生效,也可以针对目录生效,这和SUID明显不同。如果针对文件,SGID的含义如下:
☆ 只有可执行的二进制程序才能设置SGID权限
☆ 命令执行者要对该程序拥有x(执行)权限
☆ 命令执行在执行程序的时候,组身份升级为该程序文件的属组
☆ SetGID权限同样只在该程序执行过程中有效,也就是说组身份改变只在程序执行过程中有效
~ ls -l /var/lib/mlocate/mlocate.db
-rw-r----- 1 root slocate 6469897 Aug 13 03:06 /var/lib/mlocate/mlocate.db
大家发现属主权限是 r、w,属组权限是r,但是其他人权限是 0 :
~ ls -l /usr/bin/locate
-rwx--s--x 1 root slocate 40520 Apr 11 2018 /usr/bin/locate
当普通用户user1执行locate命令时,会发生如下事情:
2)针对目录的作用
如果SGID针对目录设置,含义如下:
这样写的实在太难看明白了,举个例子:
~ cd /tmp/
#进入临时目录做此实验。因为临时目录才允许普通用户修改
~ mkdir dtest
#建立测试目录
~ chmod g+s dtest
#给测试目录赋予SGID
~ ls -ld dtest/
drwxr-sr-x 2 root root 6 Aug 13 12:26 dtest/
#SGID已经生效
~ chmod 777 dtest/
#给测试目录权限,让普通用户可以写
~ su - user1
#切换成普通用户user1
$ cd /tmp/dtest/
#普通用户进入测试目录
$ touch abc
#普通用户建立 abc 文件
$ ls -l abc
-rw-rw-r-- 1 user1 root 0 Aug 13 12:41 abc
#若不添加SGID权限,那么普通用户创建的文件所属组依旧是普通用户
#abc文件的默认属组不再是user1用户组,而变成了dtest组的属组root
Sticky BIT粘着位,也简称为SBIT。SBIT目前仅针对目录有效,它的作用如下:
~ ls -ld /tmp/
drwxrwxrwt. 8 root root 105 Aug 13 13:04 /tmp/
~ ls -l
total 0
-rw-r--r-- 1 root root 0 Aug 13 13:05 abc
-rw-rw-r-- 1 user1 user1 0 Aug 13 13:05 user1.txt
-rw-rw-r-- 1 user2 user2 0 Aug 13 13:05 user2.txt
#切换到 user1 执行删除 user2 文件
~ su - user1
$ rm -rf /tmp/user2.txt
rm: cannot remove ‘/tmp/user2.txt’: Operation not permitted
特殊权限这样来表示:
~ chmod 4755 ftest
#赋予SUID权限
~ chmod 2755 ftest
#赋予SGID权限
~ mkdir dtest
~ chmod 1755 dtest
#赋予SBIT权限.
##SBIT只对目录有效,所以建立测试目录,并赋予SBIT
chattr命令 用来改变文件属性。这项指令可改变存放在ext2文件系统上的文件或目录属性,这些属性共有以下8种模式:
chattr [+-=] [选项] 文件或者目录名
选项:
+:增加权限
-:删除权限
=:等于某个权限
i:如果对文件设置i属性,那么不允许对文件进行删除、改名,也不能添加和修改数据;如果对目录设置i属性,
那么只能修改目录下文件的数据,但不允许建立和删除文件。
a:如果对文件设置a属性,那么只能在文件中增加数据,但是不能删除也不能修改数据;
如果对目录设置a属性,那么只允许在目录中建立和修改文件,但是不允许删除
e:Linux中绝大多数的文件都默认拥有e属性。表示该文件是使用ext文件系统进行存储的,
而且不能使用“chattr -e”命令取消e属性。
选项:
a:让文件或目录仅供附加用途;
b:不更新文件或目录的最后存取时间;
c:将文件或目录压缩后存放;
d:将文件或目录排除在倾倒操作之外;
i:不得任意更动文件或目录;
s:保密性删除文件或目录;
S:即时更新文件或目录;
u:预防意外删除。
-R:递归处理,将指令目录下的所有文件及子目录一并处理;
-v<版本编号>:设置文件或目录版本;
-V:显示指令执行过程;
+<属性>:开启文件或目录的该项属性;
-<属性>:关闭文件或目录的该项属性;
=<属性>:指定文件或目录的该项属性。
范例:
#进入到测试目录
~ cd /tmp
~ touch abc
#添加 -i 权限
~ chattr +i /tmp/abc
~ lsattr -a /tmp/abc
----i----------- /tmp/abc
~ echo "Hello root" > /tmp/abc
bash: /tmp/abc: Permission denied
~ rm -rf /tmp/abc
rm: cannot remove ‘/tmp/abc’: Permission denied
#超级用户和普通用户都无法对该文件进行任何的操作
~ chattr -i /tmp/abc
~ lsattr /tmp/abc
---------------- /tmp/abc
~ rm -rf /tmp/abc
查看文件的第二扩展文件系统属性
lsattr 选项 文件名
选项:
-a:显示所有文件和目录
-d:若目标是目录,仅列出目录本身的属性,而不是子文件的
-E:可显示设备属性的当前值,但这个当前值是从用户设备数据库中获得的,而不是从设备直接获得的。
-D:显示属性的名称,属性的默认值,描述和用户是否可以修改属性值的标志。
-R:递归的操作方式;
-v(小写):显示文件或者目录版本
-V(大写):显示指令的版本信息;
#例子1:
#给文件赋予 i 属性
~ touch ftest
#建立测试文件
~ chattr +i ftest
~ rm -rf ftest
rm: cannot remove ‘ftest’: Operation not permitted
#赋予i属性后,root也不能删除
~ echo "test new" >> ftest
bash: ftest: Permission denied
#也不能修改文件的数据
#给目录赋予 i 属性
~ mkdir dtest
#建立测试目录
~ touch dtest/abc
#再建立一个测试文件 abc
~ chattr +i dtest
#给目录赋予 i 属性
~ touch dtest/bcd
touch: cannot touch ‘dtest/bcd’: Permission denied
#dtest目录不能新建文件
~ echo "test new" >> dtest/abc
~ cat dtest/abc
test new
#但是可以修改文件内容
~ rm -rf dtest/abc
rm: cannot remove ‘dtest/abc’: Permission denied
#不能删除
#例子:
~ mkdir -pv /back/log
#建立备份目录
~ chattr +a /back/log
#赋予 a 属性
~ lsattr -av /back/log
990274326 -----a---------- /back/log/.
679344668 ---------------- /back/log/..
~ cp -av /var/log/messages /back/log
#可以复制文件和新建文件到指定目录
‘/var/log/messages’ -> ‘/back/log/messages’
~ rm -rf /back/log/messages
rm: cannot remove ‘/back/log/messages’: Operation not permitted
#但是不允许删除
~ touch /tmp/abc.txt
#增加了 a 属性
~ chattr +a /tmp/abc.txt
#不能使用 vim 编辑器修改abc.txt
#只能使用 echo 追加的指令
~ echo "hello root" > /tmp/abc.txt
bash: abc.txt: Operation not permitted
~ echo "hello root" >> /tmp/abc.txt
~ cat abc.txt
hello root