一、常用的指令
1.压缩命令
tar -czvf 压缩包名称.tar.gz 要打包的目录
2.解压缩命令
tar -xzvf 压缩包名称.tar.gz
3.find命令
如果要想获取到该目录中所有以 host 开头的文件列表,可以执行如下命令:
find /etc -name "host*" -print
如果要在整个系统中搜索权限中包括 SUID 权限的所有文件(详见第 5 章),只需使用-4000 即可:
find / -perm -4000 -print
4.export命令
将一个变量指定为全局变量
WORKDIR=/home/workdir
export WORKDIR
5.curl ifconfig.me
查询本机的公网ip
5.更改文件的所有者
chown -Rf ftp /var/ftp/pub
5.指定文件只能自己查看
chmod 600 auth.smb
二、重定向
1.输入重定向与管道符
符号 | 作用 |
---|---|
命令 < 文件 | 将文件作为命令的标准输入 |
命令 << 分界符 | 从标准输入中读入,直到遇见分界符才停止 |
命令 < 文件 1 > 文件 2 | 文件 2 将文件 1 作为命令的标准输入并将标准输出到文件 2 |
2.输出重定向
符号 | 作用 |
---|---|
命令 > 文件 | 将标准输出重定向到一个文件中(清空原有文件的数据) |
命令 2> 文件 | 将错误输出重定向到一个文件中(清空原有文件的数据) |
命令 >> 文件 | 将标准输出重定向到一个文件中(追加到原有内容的后面) |
命令 2>> 文件 | 将错误输出重定向到一个文件中(追加到原有内容的后面) |
命令 >> 文件 2>&1或命令 &>> 文件 | 将标准输出与错误输出共同写入到文件中(追加到原有内容的后面) |
3.管道符
将上一个命令的输出传递给下一个命令的输入,如在重置root的密码时
echo "linuxprobe" | passwd --stdin root
4.通配符
星号(*)代表匹配零个或多个字符,问号(?)代表匹配单个字符,中括号内加上数字[0-9]代表匹配 0~9 之间的单个数字的字符,而中括号内加上字母[abc]则是代表匹配 a、 b、 c 三个字符中的任意一个字符。
匹配所有在/dev 目录中且以 sda 开头的文件:
[root@linuxprobe ~]# ls -l /dev/sda*
brw-rw----. 1 root disk 8, 0 May 4 15:55 /dev/sda
brw-rw----. 1 root disk 8, 1 May 4 15:55 /dev/sda1
brw-rw----. 1 root disk 8, 2 May 4 15:55 /dev/sda2
如果只想查看文件名为 sda 开头,但是后面还紧跟其他某一个字符的文件的相关信息,该怎么操作呢?这时就需要用到问号来进行通配了。
[root@linuxprobe ~]# ls -l /dev/sda?
brw-rw----. 1 root disk 8, 1 May 4 15:55 /dev/sda1
brw-rw----. 1 root disk 8, 2 May 4 15:55 /dev/sda2
除了使用[0-9]来匹配 0~9 之间的单个数字,也可以用[135]这样的方式仅匹配这三个指定数字中的一个,若没有匹配到,则不会显示出来:
[root@linuxprobe ~]# ls -l /dev/sda[0-9]
brw-rw----. 1 root disk 8, 1 May 4 15:55 /dev/sda1
brw-rw----. 1 root disk 8, 2 May 4 15:55 /dev/sda2
[root@linuxprobe ~]# ls -l /dev/sda[135]
brw-rw----. 1 root disk 8, 1 May 4 15:55 /dev/sda1
5.常用的转义字符
4 个最常用的转义字符如下所示。
➢ 反斜杠(\):使反斜杠后面的一个变量变为单纯的字符串。
➢ 单引号(''):转义其中所有的变量为单纯的字符串。
➢ 双引号(""):保留其中的变量属性,不进行转义处理。
➢ 反引号(``):把其中的命令执行后返回结果
6.重要的环境变量
用户执行了一条命令之后, Linux 系统中到底发生了什么事情呢?简单来说,命令在 Linux 中的执行分为 4 个步骤。
第1步:判断用户是否以绝对路径或相对路径的方式输入命令(如/bin/ls),如果是的话则直接执行。
第2步: Linux 系统检查用户输入的命令是否为“别名命令”,即用一个自定义的命令名称来替换原本的命令名称。可以用 alias 命令来创建一个属于自己的命令别名,格式为“alias 别名=命令”。若要取消一个命令别名,则是用 unalias 命令,格式为“unalias 别名”。
我们之前在使用 rm 命令删除文件时,Linux 系统都会要求我们再确认是否执行删除操作,其实这就是 Linux系统为了防止用户误删除文件而特意设置的 rm 别名命令,接下来我们把它取消掉:
[root@linuxprobe ~]# ls
anaconda-ks.cfg Documents initial-setup-ks.cfg Pictures Templates
Desktop Downloads Music Public Videos
[root@linuxprobe ~]# rm anaconda-ks.cfg
rm: remove regular file ‘anaconda-ks.cfg’? y
[root@linuxprobe~]# alias rm
alias rm='rm -i'
[root@linuxprobe ~]# unalias rm
[root@linuxprobe ~]# rm initial-setup-ks.cfg
[root@linuxprobe ~]#
第3步: Bash 解释器判断用户输入的是内部命令还是外部命令。内部命令是解释器内部的指令,会被直接执行;而用户在绝大部分时间输入的是外部命令,这些命令交由步骤 4 继续处理。可以使用“type 命令名称”来判断用户输入的命令是内部命令还是外部命令。
第4步:系统在多个路径中查找用户输入的命令文件,而定义这些路径的变量叫作 PATH, 可以简单地把它理解成是“解释器的小助手”,作用是告诉 Bash 解释器待执行的命令可能存放的位置,然后 Bash 解释器就会乖乖地在这些位置中逐个查找。 PATH 是由多个路径值组成的变量,每个路径值之间用冒号间隔,对这些路径的增加和删除操作将影响到 Bash 解释器对Linux 命令的查找。
[root@linuxprobe ~]# echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
[root@linuxprobe ~]# PATH=$PATH:/root/bin
[root@linuxprobe ~]# echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin
三、软件的配置
1、配置yum仓库
第1步:进入到/etc/yum.repos.d/目录中(因为该目录存放着 Yum 软件仓库的配置文件)。
第2步: 使用 Vim 编辑器创建一个名为 rhel7.repo 的新配置文件(文件名称可随意,但后缀必须为.repo),逐项写入下面加粗的配置参数并保存退出(不要写后面的中文注释)。
➢ 【rhel-media】: Yum 软件仓库唯一标识符,避免与其他仓库冲突。
➢ 【name=linuxprobe】: Yum 软件仓库的名称描述,易于识别仓库用处。
➢ 【baseurl=file://media/cdrom】: 提供的方式包括 FTP(ftp://..)、 HTTP(http://..)、本地(file:///..)。
➢ 【enabled=1】: 设置此源是否可用; 1 为可用, 0 为禁用。
➢ 【gpgcheck=1】: 设置此源是否校验文件; 1 为校验, 0 为不校验。
➢ 【gpgkey=file://media/cdrom/RPM-GPG-KEY-redhat-release】: 若上面参数开启校验,那么请指定公钥文件地址。
第3步:按配置参数的路径挂载光盘,并把光盘挂载信息写入到/etc/fstab 文件中。
第4步:使用“yum install httpd -y”命令检查 Yum 软件仓库是否已经可用。进入/etc/yum.repos.d 目录中后创建 Yum 配置文件:
[root@linuxprobe ~]# cd /etc/yum.repos.d/
[root@linuxprobe yum.repos.d]# vim rhel7.repo
[rhel7]
name=rhel7
baseurl=file:///media/cdrom
enabled=1
gpgcheck=0
创建挂载点后进行挂载操作,并设置成开机自动挂载(详见第 6 章)。 尝试使用 Yum 软件仓库来安装 Web 服务,出现 Complete! 则代表配置正确:
[root@linuxprobe yum.repos.d]# mkdir -p /media/cdrom
[root@linuxprobe yum.repos.d]# mount /dev/cdrom /media/cdrom
mount: /dev/sr0 is write-protected, mounting read-only
[root@linuxprobe yum.repos.d]# vim /etc/fstab
/dev/cdrom /media/cdrom iso9660 defaults 0 0
[root@linuxprobe ~]# yum install httpd
Loaded plugins: langpacks, product-id, subscription-manager
………………省略部分输出信息………………
Dependencies Resolved
===============================================================================
Package Arch Version Repository Size
===============================================================================
Installing:
httpd x86_64 2.4.6-17.el7 rhel 1.2 M
Installing for dependencies:
apr x86_64 1.4.8-3.el7 rhel 103 k
apr-util x86_64 1.5.2-6.el7 rhel 92 k
httpd-tools x86_64 2.4.6-17.el7 rhel 77 k
mailcap noarch 2.1.41-2.el7 rhel 31 k
Transaction Summary
===============================================================================
Install 1 Package (+4 Dependent packages)
Total download size: 1.5 M
Installed size: 4.3 M
Is this ok [y/d/N]: y
Downloading packages:
………………省略部分输出信息………………
Complete!
四、Shell脚本
可以将 Shell 终端解释器当作人与计算机硬件之间的“翻译官”,它作为用户与 Linux 系统内部的通信媒介,除了能够支持各种变量与参数外,还提供了诸如循环、分支等高级编程语言才有的控制结构特性。
#!/bin/bash
#For Example BY linuxprobe.com
pwd
ls -al
在上面的这个 example.sh 脚本中实际上出现了三种不同的元素:
- 第一行的脚本声明(#!)用来告诉系统使用哪种 Shell 解释器来执行该脚本;
- 第二行的注释信息(#)是对脚本功能和某些命令的介绍信息,使得自己或他人在日后看到这个脚本内容时,可以快速知道该脚本的作用或一些警告信息;
- 第三、四行的可执行语句也就是我们平时执行的 Linux 命令了。
1. 接收用户的参数
脚本:
#!/bin/bash
echo "当前脚本名称为$0"
echo "总共有$#个参数,分别是$*。 "
echo "第 1 个参数为$1,第 5 个为$5。 "
运行:
[root@linuxprobe ~]# sh example.sh one two three four five six
当前脚本名称为 example.sh
总共有 6 个参数,分别是 one two three four five six。
第 1 个参数为 one,第 5 个为 five。
2. 判断用户的参数
按照测试对象来划分,条件测试语句可以分为 4 种:
➢ 文件测试语句;
➢ 逻辑测试语句;
➢ 整数值比较语句;
➢ 字符串比较语句。
文件测试所用的参数:
运算符 | 作用 |
---|---|
-d | 测试文件是否为目录类型 |
-e | 测试文件是否存在 |
-f | 判断是否为一般文件 |
-r | 测试当前用户是否有权限读取 |
-w | 测试当前用户是否有权限写入 |
-x | 测试当前用户是否有权限执行 |
可用的整数比较运算符
运算符 | 作用 |
---|---|
-eq | 是否等于 |
-ne | 是否不等于 |
-gt | 是否大于 |
-lt | 是否小于 |
-le | 是否等于或小于 |
-ge | 是否大于或等于 |
流程控制语句
1. if 条件测试语句
双分支的测试语句:
#!/bin/bash
ping -c 3 -i 0.2 -W 3 $1 &> /dev/null
if [ $? -eq 0 ]
then
echo "Host $1 is On-line."
else
echo "Host $1 is Off-line."
fi
多分支的测试语句:
#!/bin/bash
read -p "Enter your score(0-100): " GRADE
if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ] ; then
echo "$GRADE is Excellent"
elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ] ; then
echo "$GRADE is Pass"
else
echo "$GRADE is Fail"
fi
[root@linuxprobe ~]# bash chkscore.sh
Enter your score(0-100): 88
88 is Excellent
[root@linuxprobe ~]# bash chkscore.sh
Enter your score(0-100): 80
80 is Pass
[root@linuxprobe ~]# bash chkscore.sh
Enter your score(0-100): 30
30 is Fail
[root@linuxprobe ~]# bash chkscore.sh
Enter your score(0-100): 200
200 is Fail
2. for 条件循环语句
#!/bin/bash
read -p "Enter The Users Password : " PASSWD
for UNAME in `cat users.txt`
do
id $UNAME &> /dev/null
if [ $? -eq 0 ]
then
echo "Already exists"
else
useradd $UNAME &> /dev/null
echo "$PASSWD" | passwd --stdin $UNAME &> /dev/null
if [ $? -eq 0 ]
then
echo "$UNAME , Create success"
else
echo "$UNAME , Create failure"
fi
fi
done
运行上面的脚本:
[root@linuxprobe ~]# bash Example.sh
Enter The Users Password : linuxprobe
andy , Create success
barry , Create success
carl , Create success
duke , Create success
eric , Create success
george , Create success
3. while 条件循环语句
#!/bin/bash
PRICE=$(expr $RANDOM % 1000)
TIMES=0
echo "商品实际价格为 0-999 之间,猜猜看是多少? "
while true
do
read -p "请输入您猜测的价格数目: " INT
let TIMES++
if [ $INT -eq $PRICE ] ; then
echo "恭喜您答对了,实际价格是 $PRICE"
echo "您总共猜测了 $TIMES 次"
exit 0
elif [ $INT -gt $PRICE ] ; then
echo "太高了! "
else
echo "太低了! "
fi
done
4.case 条件测试语句
#!/bin/bash
read -p "请输入一个字符,并按 Enter 键确认: " KEY
case "$KEY" in
[a-z]|[A-Z])
echo "您输入的是 字母。 "
;;
[0-9])
echo "您输入的是 数字。 "
;;
*)
echo "您输入的是 空格、功能键或其他控制字符。 "
esac
运行以上脚本:
[root@linuxprobe ~]# bash Checkkeys.sh
请输入一个字符,并按 Enter 键确认: 6
您输入的是 数字。
[root@linuxprobe ~]# bash Checkkeys.sh
请输入一个字符,并按 Enter 键确认: p
您输入的是 字母。
[root@linuxprobe ~]# bash Checkkeys.sh
请输入一个字符,并按 Enter 键确认: ^[[15~
您输入的是 空格、功能键或其他控制字符。
计划任务服务程序
计划任务分为一次性计划任务与长期性计划任务:
➢ 一次性计划任务:今晚 11 点 30 分开启网站服务。
➢ 长期性计划任务:每周一的凌晨 3 点 25 分把/home/wwwroot 目录打包备份为backup.tar.gz。
例如,使用下述命令将系统设置为在今晚 23:30 分自动重启网站服务。
[root@linuxprobe ~]# at 23:30
at > systemctl restart httpd
at > 此处请同时按下 Ctrl + D 组合键来结束编写计划任务
job 3 at Mon Apr 27 23:30:00 2017
[root@linuxprobe ~]# at -l
如果想挑战一下难度更大但简捷性更高的方式,可以把前面学习的管道符(任意门)放到两条命令之间,让 at 命令接收前面 echo 命令的输出信息,以达到通过非交互式的方式创建计划一次性任务的目的
[root@linuxprobe ~]# echo "systemctl restart httpd" | at 23:30
job 4 at Mon Apr 27 23:30:00 2017
[root@linuxprobe ~]# at -l
3 Mon Apr 27 23:30:00 2017 a root
4 Mon Apr 27 23:30:00 2017 a root
如果我们不小心设置了两个一次性计划任务,可以使用下面的命令轻松删除其中一个:
[root@linuxprobe ~]# atrm 3
[root@linuxprobe ~]# at -l
4 Mon Apr 27 23:30:00 2017 a root
定时语句的语法:
使用 crond 设置任务的参数字段说明:
运算符 | 作用 |
---|---|
分 | 取值为 0~59 的整数 |
时 | 取值为 0~23 的任意整数 |
日 | 取值为 1~31 的任意整数 |
月 | 取值为 1~12 的任意整数 |
星期 | 取值为 0~7 的任意整数,其中 0 与 7 均为星期日 |
命令 | 要执行的命令或程序脚本 |
假设在每周一、三、五的凌晨 3 点 25 分,都需要使用 tar 命令把某个网站的数据目录进行打包处理,使其作为一个备份文件。我们可以使用 crontab -e 命令来创建计划任务。为自己创建计划任务无需使用-u 参数,具体的实现效果的参数如 crontab -l 命令结果所示:
[root@linuxprobe ~]# crontab -e
no crontab for root - using an empty one
crontab: installing new crontab
[root@linuxprobe ~]# crontab -l
25 3 * * 1,3,5 /usr/bin/tar -czvf backup.tar.gz /home/wwwroot
需要说明的是,除了用逗号(,)来分别表示多个时间段,例如“8,9,12”表示 8 月、 9 月和 12 月。还可以用减号(-)来表示一段连续的时间周期(例如字段“日”的取值为“12-15”,则表示每月的 12~15 日)。以及用除号(/)表示执行任务的间隔时间(例如“/2”表示每隔2 分钟执行一次任务)。如果在 crond 服务中需要同时包含多条计划任务的命令语句,应每行仅写一条。尤其需要注意的是,在 crond 服务的计划任务参数中,所有命令一定要用绝对路径的方式来写,如果不知道绝对路径,请用 whereis 命令进行查询。*
注意点:
➢ 在 crond 服务的配置参数中,可以像 Shell 脚本那样以#号开头写上注释信息,这样
在日后回顾这段命令代码时可以快速了解其功能、需求以及编写人员等重要信息。
➢ 计划任务中的“分”字段必须有数值,绝对不能为空或是*号,而“日”和“星期”字
段不能同时使用,否则就会发生冲突
五、用户和组
1. 常用的一些命令
useradd 命令:
参数 | 作用 |
---|---|
-d | 指定用户的家目录(默认为/home/username) |
-e | 账户的到期时间,格式为 YYYY-MM-DD. |
-u | 指定该用户的默认 UID |
-g | 指定一个初始的用户基本组(必须已存在) |
-G | 指定一个或多个扩展用户组 |
-N | 不创建与用户同名的基本用户组 |
-s | 指定该用户的默认 Shell 解释器 |
实例:
[root@linuxprobe ~]# useradd -d /home/linux -u 8888 -s /sbin/nologin linuxprobe
[root@linuxprobe ~]# id linuxprobe
uid=8888(linuxprobe) gid=8888(linuxprobe) groups=8888(linuxprobe)
groupadd 命令:
groupadd 命令用于创建用户组,格式为“groupadd [选项] 群组名”。
[root@linuxprobe ~]# groupadd ronny
usermod 命令:
usermod 命令用于修改用户的属性,格式为“usermod [选项] 用户名”。
参数 | 作用 |
---|---|
-c | 填写用户账户的备注信息 |
-d -m | 参数-m 与参数-d 连用,可重新指定用户的家目录并自动把旧的数据转移过去 |
-e | 账户的到期时间,格式为 YYYY-MM-DD |
-g | 变更所属用户组 |
-G | 变更扩展用户组 |
-L | 锁定用户禁止其登录系统 |
-U | 解锁用户,允许其登录系统 |
-s | 变更默认终端 |
-u | 修改用户的 UID |
将用户 linuxprobe 加入到 root 用户组中,这样扩展组列表中则会出现 root 用户组的
字样,而基本组不会受到影响,如下:
[root@linuxprobe ~]# usermod -G root linuxprobe
[root@linuxprobe ~]# id linuxprobe
uid=1000(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe),0(root)
passwd 命令:
passwd 命令用于修改用户密码、过期时间、认证信息等,格式为“passwd [选项] [用户名]”。
参数 | 作用 |
---|---|
-l | 锁定用户,禁止其登录 |
-u | 解除锁定,允许用户登录 |
--stdin | 允许通过标准输入修改用户密码,如 echo "NewPassWord" | passwd --stdin Username |
-d | 使该用户可用空密码登录系统 |
-e | 强制用户在下次登录时修改密码 |
-S | 显示用户的密码是否被锁定,以及密码所采用的加密算法名称 |
[root@linuxprobe ~]# passwd
Changing password for user root.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
[root@linuxprobe ~]# passwd linuxprobe
Changing password for user linuxprobe.
New password:
Retype new password:
passwd: all authentication tokens updated successfully
假设您有位同事正在度假,而且假期很长,那么可以使用 passwd 命令禁止该用户登录系统,等假期结束回归工作岗位时,再使用该命令允许用户登录系统,而不是将其删除。这样既保证了这段时间内系统的安全,也避免了频繁添加、删除用户带来的麻烦:
[root@linuxprobe ~]# passwd -l linuxprobe
Locking password for user linuxprobe.
passwd: Success
[root@linuxprobe ~]# passwd -S linuxprobe
linuxprobe LK 2017-12-26 0 99999 7 -1 (Password locked.)
[root@linuxprobe ~]# passwd -u linuxprobe
Unlocking password for user linuxprobe.
passwd: Success
[root@linuxprobe ~]# passwd -S linuxprobe
linuxprobe PS 2017-12-26 0 99999 7 -1 (Password set, SHA512 crypt.)
userdel 命令:
userdel 命令用于删除用户,格式为“userdel [选项] 用户名”。
参数 | 作用 |
---|---|
-f | 强制删除用户 |
-r | 同时删除用户及用户家目录 |
2.文件权限与归属
尽管在 Linux 系统中一切都是文件,但是每个文件的类型不尽相同,因此 Linux 系统使
用了不同的字符来加以区分,常见的字符如下所示。
字符 | 含义 |
---|---|
- | 普通文件。 |
d | 目录文件。 |
l | 链接文件。 |
b | 块设备文件。 |
c | 字符设备文件。 |
p | 管道文件。 |
对于一般文件来说,权限比较容易理解;但是,对于目录文件来说,理解其权限设置来就不那么容易了。很多资深 Linux 用户其实也没有真正搞明白。他们的区别对比如下表:
字符 | 文件含义 | 目录含义 |
---|---|---|
可读(r) | 表示能够读取文件的实际内容; | 表示能够读取目录内的文件列表 |
可写(w) | 表示能够编辑、新增、修改、删除文件的实际内容; | 表示能够在目录内新增、删除、重命名文件 |
可执行(x) | 表示能够运行一个脚本程序。 | 表示能够进入该目录 |
文件权限的字符与数字表示:
3.文件的特殊权限
在复杂多变的生产环境中,单纯设置文件的 rwx 权限无法满足我们对安全和灵活性的需
求,因此便有了 SUID、 SGID 与 SBIT 的特殊权限位。
SUID
SUID 是一种对二进制程序进行设置的特殊权限,可以让二进制程序的执行者临时拥有属主的权限(仅对拥有执行权限的二进制程序有效)。例如,所有用户都可以执行 passwd 命令来修改自己的用户密码,而用户密码保存在/etc/shadow 文件中。
查看 passwd 命令属性时发现所有者的权限由 rwx 变成了 rws,其中 x 改变成 s 就意味着该文件被赋予了 SUID 权限。另外有读者会好奇,那么如果原本的权限是 rw-呢?如果原先权限位上没有 x 执行权限,那么被赋予特殊权限后将变成大写的 S。
[root@linuxprobe ~]# ls -l /etc/shadow
----------. 1 root root 1004 Jan 3 06:23 /etc/shadow
[root@linuxprobe ~]# ls -l /bin/passwd
-rwsr-xr-x. 1 root root 27832 Jan 29 2017 /bin/passwd
SGID
SGID 主要实现如下两种功能:
➢ 让执行者临时拥有属组的权限(对拥有执行权限的二进制程序进行设置)
➢ 在某个目录中创建的文件自动继承该目录的用户组(只可以对目录进行设置)
举例来说,在早期的 Linux 系统中,/dev/kmem 是一个字符设备文件,用于存储内核程序要访问的数据,权限为:
cr--r----- 1 root system 2, 1 Feb 11 2017 kmem
大家看出问题了吗?除了 root 管理员或属于 system 组成员外,所有用户都没有读取该文件的权限。由于在平时我们需要查看系统的进程状态,为了能够获取到进程的状态信息,可在用于查看系统进程状态的 ps 命令文件上增加 SGID 特殊权限位。查看 ps 命令文件的属性信息:
-r-xr-sr-x 1 bin system 59346 Feb 11 2017 ps
这样一来,由于 ps 命令被增加了 SGID 特殊权限位,所以当用户执行该命令时,也就临
时获取到了 system 用户组的权限,从而可以顺利地读取设备文件了。
SGID 的第二个功能,即某个目录中创建的文件,将会与该目录所属的用户组一致,这样可以更便捷的赋予权限。
[root@linuxprobe ~]# cd /tmp
[root@linuxprobe tmp]# mkdir testdir
[root@linuxprobe tmp]# ls -ald testdir/
drwxr-xr-x. 2 root root 6 Feb 11 11:50 testdir/
[root@linuxprobe tmp]# chmod -Rf 777 testdir/
[root@linuxprobe tmp]# chmod -Rf g+s testdir/
[root@linuxprobe tmp]# ls -ald testdir/
drwxrwsrwx. 2 root root 6 Feb 11 11:50 testdir/
在testdir创建的文件会自动添加到root组当中
chmod 命令:用来设置文件或目录的权限,格式为“chmod[参数] 权限 文件或目录名称”。
[root@linuxprobe ~]# chmod 760 test
[root@linuxprobe ~]# ls -l test
-rwxrw----. 1 linuxprobe root 15 Feb 11 11:50 test
chown 命令:设置文件或目录的所有者和所属组,其格式为“chown [参数] 所有者:所属组 文件或目录名称”。
[root@linuxprobe ~]# ls -l test
-rwxrw----. 1 linuxprobe root 15 Feb 11 11:50 test
[root@linuxprobe ~]# chown root:bin test
[root@linuxprobe ~]# ls -l test
-rwxrw----. 1 root bin 15 Feb 11 11:50 test
SBIT
现在,大学里的很多老师都要求学生将作业上传到服务器的特定共享目录中,但总是有几个“破坏分子”喜欢删除其他同学的作业,这时就要设置 SBIT(Sticky Bit)特殊权限位了(也可以称之为特殊权限位之粘滞位)。 SBIT 特殊权限位可确保用户只能删除自己的文件,而不能删除其他用户的文件。换句话说,当对某个目录设置了 SBIT 粘滞位权限后,那么该目录中的文件就只能被其所有者执行删除操作了
在linux中,/tmp目录下的文件默认是带有SBIT特殊权限位的,如果不是你创建的文件,你是无法删除的,如下:
$ rm -rf test
rm: cannot remove ‘test’: Operation not permitted
如果要给文件赋予SBIT特殊权限位,使用以下指令:
chmod -R o+t linux/
4.文件的隐藏属性
Linux 系统中的文件除了具备一般权限和特殊权限之外,还有一种隐藏权限,即被隐藏起
来的权限,默认情况下不能直接被用户发觉。
chattr 命令
chattr 命令中用于隐藏权限的参数及其作用
参数 | 作用 |
---|---|
i | 无法对文件进行修改;若对目录设置了该参数,则仅能修改其中的子文件内容而不能新建或删除文件 |
a | 仅允许补充(追加)内容,无法覆盖/删除内容(Append Only) |
S | 文件内容在变更后立即同步到硬盘(sync) |
s | 彻底从硬盘中删除,不可恢复(用 0 填充原文件所在硬盘区域) |
A | 不再修改这个文件或目录的最后访问时间(atime) |
b | 不再修改文件或目录的存取时间 |
D | 检查压缩文件中的错误 |
d | 使用 dump 命令备份时忽略本文件/目录 |
c | 默认将文件或目录进行压缩 |
u | 当删除该文件后依然保留其在硬盘中的数据,方便日后恢复 |
t | 让文件系统支持尾部合并(tail-merging) |
X | 可以直接访问压缩文件中的内容 |
一个简单示例:
[root@linuxprobe ~]# echo "for Test" > linuxprobe
[root@linuxprobe ~]# chattr +a linuxprobe
[root@linuxprobe ~]# rm linuxprobe
rm: remove regular file ‘linuxprobe’? y
rm: cannot remove ‘linuxprobe’: Operation not permitted
lsattr 命令
一旦使用 lsattr 命令后,文件上被赋予的隐藏权限马上就会原形毕露。此时可以按照显示
的隐藏权限的类型(字母),使用 chattr 命令将其去掉:
[root@linuxprobe ~]# lsattr linuxprobe
-----a---------- linuxprobe
[root@linuxprobe ~]# chattr -a linuxprobe
[root@linuxprobe ~]# lsattr linuxprobe
---------------- linuxprobe
[root@linuxprobe ~]# rm linuxprobe
rm: remove regular file ‘linuxprobe’? y
文件访问控制列表 ACL
如果希望对某个文件的权限进行更精细的分配,即本来只能给属主或属组赋予权限,这时候想要对属主或属组赋予rwx的权限,就需要用到文件的访问控制列表(ACL)了。
setfacl 命令
setfacl 命令用于管理文件的 ACL 规则,格式为“setfacl [参数] 文件名称”。
下面来设置用户在/root 目录上的权限:
[root@linuxprobe ~]# setfacl -Rm u:linuxprobe:rwx /root
[root@linuxprobe ~]# su - linuxprobe
Last login: Sat Mar 21 15:45:03 CST 2017 on pts/1
[linuxprobe@linuxprobe ~]$ cd /root
[linuxprobe@linuxprobe root]$ ls
anaconda-ks.cfg Downloads Pictures Public
[linuxprobe@linuxprobe root]$ cat anaconda-ks.cfg
[linuxprobe@linuxprobe root]$ exit
设置用户ACL访问控制的权限格式:setfacl -Rm u:用户名:权限 文件,如下:
setfacl -Rm u:linuxprobe:rwx /root
设置用户组ACL访问控制的权限格式:setfacl -Rm g:组名:权限 文件,如下:
setfacl –Rm g:linuxprobe:rwx /root
如何知道某个文件是否赋予了ACL?
[root@linuxprobe ~]# ls -ld /root
dr-xrwx---+ 14 root root 4096 May 4 2017 /root
如果文件的权限的最后一个位变成了+号,代表文件被赋予了ACL;
getfacl 命令
getfacl 命令用于显示文件上设置的 ACL 信息,格式为“getfacl 文件名称”。
5.su 命令与 sudo 服务
sudo 命令用于给普通用户提供额外的权限来完成原本 root 管理员才能完成的任务,格式
为“sudo [参数] 命令名称”。
sudo 服务中的可用参数以及作用
参数 | 作用 |
---|---|
-h | 列出帮助信息 |
-l | 列出当前用户可执行的命令 |
-u | 用户名或 UID 值 以指定的用户身份执行命令 |
-k | 清空密码的有效时间,下次执行 sudo 时需要再次进行密码验证 |
-b | 在后台执行指定的命令 |
-p | 更改询问密码的提示语 |
visudo 命令
visudo 命令可用于配置用户权限,配置 sudo 命令的配置文件时,其操作方法与 Vim 编辑器中用到的方法一致,因此在编写完成后记得在末行模式下保存并退出。在 sudo 命令的配置文件中,按照下面的格式将第 99 行(大约)填写上指定的信息。
谁可以使用 允许使用的主机 =(以谁的身份) 可执行命令的列表
六、存储结构和磁盘划分
1.几个基本概念:
- 主分区:相当于C盘,里面包含了启动的引导文件,英文名叫做MBR
- 拓展分区:主分区以外的分区
-
逻辑分区:拓展分区下面的子分区,比如D盘、E盘、F盘,与拓展分区是包含的关系,他们的关系如下图:
2.linux中目录的结构
3.linux中常见的物理设备及名称
4.挂载硬件设备
首先要知道一个问题,为什么我们可以随意操作文件?
主要原因是这样的,由于linux是一个很大的开源生态系统,所以它的文件系统有很多,不同的文件系统其读写方式肯定是不一样的,常见的文件系统有这些:Ext3,Ext4,XFS...,见下图:
这些文件系统的底层是硬件设备,文件系统是硬件设备的一套规范,但这些文件系统最后被VFS这个操作接口统一了,所以我们的用的cp,rm等指令都是这个VFS提供的。
那为什么又要挂载呢?
刘遄老师有一个最简单、最贴切的解释:当用户需要使用硬盘设备或分区中的数据时,需要先将其与一个已存在的目录文件进行关联,而这个关联动作就是“挂载”。
5.mount 命令
mount 命令用于挂载文件系统,格式为“mount 文件系统 挂载目录”。
例如,要把设备/dev/sdb2 挂载到/backup 目录,只需要在 mount 命令中填写设备与挂载目录
参数就行,系统会自动去判断要挂载文件的类型,因此只需要执行下述命令即可:
[root@linuxprobe ~]# mount /dev/sdb2 /backup
虽然按照上面的方法执行 mount 命令后就能立即使用文件系统了,但系统在重启后挂
载就会失效,也就是说我们需要每次开机后都手动挂载一下。
如果想让硬件设备和目录永久地进行自动关联,就必须把挂载信息按照指定的填写格式“设备文件 挂载目录 格式类型 权限选项 是否备份 是否自检”(各字段的意义见表 6-4)写入到/etc/fstab 文件中。这个文件中包含着挂载所需的诸多信息项目,一旦配置好之后就能一劳永逸了。
[root@linuxprobe ~]# vim /etc/fstab
# #
/etc/fstab
# Created by anaconda on Wed May 4 19:26:23 2017
# #
Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/rhel-root / xfs defaults 1 1
UUID=812b1f7c-8b5b-43da-8c06-b9999e0fe48b /boot xfs defaults 1 2
/dev/mapper /rhel-swap swap swap defaults 0 0
/dev/cdrom /media/cdrom iso9660 defaults 0 0
/dev/sdb2 /backup ext4 defaults 0 0
关注其中的:/dev/sdb2 /backup ext4 defaults 0 0,这是要添加的内容。
6.fdisk 命令
在 Linux 系统中,管理硬盘设备最常用的方法就当属 fdisk 命令了。 fdisk 命令用于管理磁盘分区,格式为“fdisk [磁盘名称]”,它提供了集添加、删除、转换分区等功能于一身的“一站式分区服务”。
7.du 命令
该命令用来查看一个或多个文件占用了多大的硬盘空间
[root@linuxprobe Desktop]# du -sh readit.txt
4.0K readit.txt
8.软硬方式链接
假如a.txt链接到b.txt,且a.txt中有内容,则:
软连接:b.txt是a.txt的快捷方式,打开b.txt 就是打开a.txt,删除a.txt,b.txt将打不开,指令为ln -s a.txt b.txt
硬连接:是一种inode的引用,打开b.txt 就是打开a.txt,删除a.txt,b.txt仍然能打开,且内容就是a.txt的内容,指令为ln a.txt b.txt
五、用户和组
九、网络
1、网卡配置
网卡 IP 地址配置的是否正确是两台服务器是否可以相互通信的前提。在 RHEL 5、 RHEL 6 中,网卡配置文件的前缀为 eth,第 1 块网卡为eth0,第 2 块网卡为 eth1;以此类推。而在 RHEL 7 中,网卡配置文件的前缀则以 ifcfg 开始,加上网卡名称共同组成了网卡配置文件的名字,例如 ifcfg-eno16777736;好在除了文件名变化外也没有其他大的区别。现在有一个名称为 ifcfg-eno16777736 的网卡设备,我们将其配置为开机自启动,并且 IP地址、子网、网关等信息由人工指定,其步骤应该如下所示。
第1步:首先切换到/etc/sysconfig/network-scripts 目录中(存放着网卡的配置文件)。
第2步:使用 Vim 编辑器修改网卡文件 ifcfg-eno16777736,逐项写入下面的配置参数并保存退出。由于每台设备的硬件及架构是不一样的,因此请读者使用 ifconfig 命令自行确认各自网卡的默认名称。
➢ 设备类型: TYPE=Ethernet
➢ 地址分配模式: BOOTPROTO=static
➢ 网卡名称: NAME=eno16777736
➢ 是否启动: ONBOOT=yes
➢ IP 地址: IPADDR=192.168.10.10
➢ 子网掩码: NETMASK=255.255.255.0
➢ 网关地址: GATEWAY=192.168.10.1
➢ DNS 地址: DNS1=192.168.10.1
第3步:重启网络服务并测试网络是否联通。进入到网卡配置文件所在的目录,然后编辑网卡配置文件,在其中填入下面的信息:
[root@linuxprobe ~]# cd /etc/sysconfig/network-scripts/
[root@linuxprobe network-scripts]# vim ifcfg-eno16777736
TYPE=Ethernet
BOOTPROTO=static
NAME=eno16777736
ONBOOT=yes
IPADDR=192.168.10.10
NETMASK=255.255.255.0
GATEWAY=192.168.10.1
DNS1=192.168.10.1
执行重启网卡设备的命令(在正常情况下不会有提示信息),然后通过 ping 命令测试网络能否联通。由于在 Linux 系统中 ping 命令不会自动终止,因此需要手动按下 Ctrl-c 键来强行结束进程。
[root@linuxprobe network-scripts]# systemctl restart network
[root@linuxprobe network-scripts]# ping 192.168.10.10
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=0.081 ms
64 bytes from 192.168.10.10: icmp_seq=2 ttl=64 time=0.083 ms
64 bytes from 192.168.10.10: icmp_seq=3 ttl=64 time=0.059 ms
64 bytes from 192.168.10.10: icmp_seq=4 ttl=64 time=0.097 ms
^C
--- 192.168.10.10 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.059/0.080/0.097/0.013 ms
2、网络防火墙
相较于传统的防火墙管理配置工具, firewalld 支持动态更新技术并加入了区域(zone)的概念。简单来说,区域就是 firewalld 预先准备了几套防火墙策略集合(策略模板),用户可以根据生产场景的不同而选择合适的策略集合,从而实现防火墙策略之间的快速切换。例如,我们有一台笔记本电脑,每天都要在办公室、咖啡厅和家里使用。按常理来讲,这三者的安全性按照由高到低的顺序来排列,应该是家庭、公司办公室、咖啡厅。当前,我们希望为这台笔记本电脑指定如下防火墙策略规则:在家中允许访问所有服务;在办公室内仅允许访问文件共享服务;在咖啡厅仅允许上网浏览。在以往,我们需要频繁地手动设置防火墙策略规则,而现在只需要预设好区域集合,然后只需轻点鼠标就可以自动切换了,从而极大地提升了防火墙策略的应用效率。 firewalld 中常见的区域名称(默认为 public)以及相应的策略规则如表所示。
区域 | 默认策略规则 |
---|---|
trusted | 允许所有的数据包 |
home | 拒绝流入的流量,除非与流出的流量相关;而如果流量与 ssh、 mdns、 ipp-client、amba-client 与 dhcpv6-client 服务相关,则允许流量《Linux 就该这么学》 |
internal | 等同于 home 区域 |
work | 拒绝流入的流量,除非与流出的流量数相关;而如果流量与 ssh、 ipp-client 与 |
dhcpv6-client | 服务相关,则允许流量 |
public | 拒绝流入的流量,除非与流出的流量相关;而如果流量与 ssh、 dhcpv6-client 服务相关,则允许流量 |
external | 拒绝流入的流量,除非与流出的流量相关;而如果流量与 ssh 服务相关,则允许流量 |
dmz | 拒绝流入的流量,除非与流出的流量相关;而如果流量与 ssh 服务相关,则允许流量 |
block | 拒绝流入的流量,除非与流出的流量相关 |
drop | 拒绝流入的流量,除非与流出的流量相关 |
2.1终端管理工具
firewallcmd 是 firewalld 防火墙配置管理工具的 CLI(命令行界面)版本。它的参数一般都是以“长格式”来提供的,可以用 Tab 键来补齐。
查看 firewalld 服务当前所使用的区域:
[root@linuxprobe ~]# firewall-cmd --get-default-zone
public
查询 eno16777728 网卡在 firewalld 服务中的区域:
[root@linuxprobe ~]# firewall-cmd --get-zone-of-interface=eno16777728
public
把 firewalld 服务中 eno16777728 网卡的默认区域修改为 external,并在系统重启后生效。分别查看当前与永久模式下的区域名称:
[root@linuxprobe ~]# firewall-cmd --permanent --zone=external --change-interface=
eno16777728
success
[root@linuxprobe ~]# firewall-cmd --get-zone-of-interface=eno16777728
public
[root@linuxprobe ~]# firewall-cmd --permanent --get-zone-of-interface=eno16777728
external
把 firewalld 服务的当前默认区域设置为 public:
[root@linuxprobe ~]# firewall-cmd --set-default-zone=public
success
[root@linuxprobe ~]# firewall-cmd --get-default-zone
public
启动/关闭 firewalld 防火墙服务的应急状况模式,阻断一切网络连接(当远程控制服务器
时请慎用):
[root@linuxprobe ~]# firewall-cmd --panic-on
success
[root@linuxprobe ~]# firewall-cmd --panic-off
success
查询 public 区域是否允许请求 SSH 和 HTTPS 协议的流量:
[root@linuxprobe ~]# firewall-cmd --zone=public --query-service=ssh
yes
[root@linuxprobe ~]# firewall-cmd --zone=public --query-service=https
no
把 firewalld 服务中请求 HTTPS 协议的流量设置为永久允许,并立即生效:
[root@linuxprobe ~]# firewall-cmd --zone=public --add-service=https
185
success
[root@linuxprobe ~]# firewall-cmd --permanent --zone=public --add-service=https
success
[root@linuxprobe ~]# firewall-cmd --reload
success
把 firewalld 服务中请求 HTTP 协议的流量设置为永久拒绝,并立即生效:
[root@linuxprobe ~]# firewall-cmd --permanent --zone=public --remove-service=http
success
[root@linuxprobe ~]# firewall-cmd --reload
success
把在 firewalld 服务中访问 8080 和 8081 端口的流量策略设置为允许,但仅限当前生效:
[root@linuxprobe ~]# firewall-cmd --zone=public --add-port=8080-8081/tcp
success
[root@linuxprobe ~]# firewall-cmd --zone=public --list-ports
8080-8081/tcp
把原本访问本机 888 端口的流量转发到 22 端口,要且求当前和长期均有效:
注:流量转发命令格式:firewall-cmd --permanent --zone=< > --add-forward-port=port=< >:proto=< >:toport=< >:toaddr=< IP >
[root@linuxprobe ~]# firewall-cmd --permanent --zone=public --add-forward-port=
port=888:proto=tcp:toport=22:toaddr=192.168.10.10
success
[root@linuxprobe ~]# firewall-cmd --reload
success
在客户端使用 ssh 命令尝试访问 192.168.10.10 主机的 888 端口:
[root@client A ~]# ssh -p 888 192.168.10.10
The authenticity of host '[192.168.10.10]:888 ([192.168.10.10]:888)' can't
be established.
ECDSA key fingerprint is b8:25:88:89:5c:05:b6:dd:ef:76:63:ff:1a:54:02:1a.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[192.168.10.10]:888' (ECDSA) to the list of known hosts.
[email protected]'s password: root
Last login: Sun Jul 19 21:43:48 2017 from 192.168.10.10
firewalld 中的富规则表示更细致、更详细的防火墙策略配置,它可以针对系统服务、端口号、源地址和目标地址等诸多信息进行更有针对性的策略配置。它的优先级在所有的防火墙策略中也是最高的。比如,我们可以在 firewalld 服务中配置一条富规则,使其拒绝192.168.10.0/24 网段的所有用户访问本机的 ssh 服务(22 端口):
[root@linuxprobe ~]# firewall-cmd --permanent --zone=public --add-rich-rule="
rule family="ipv4" source address="192.168.10.0/24" service name="ssh" reject"
success
[root@linuxprobe ~]# firewall-cmd --reload
success
在客户端使用 ssh 命令尝试访问 192.168.10.10 主机的 ssh 服务(22 端口):
[root@client A ~]# ssh 192.168.10.10
Connecting to 192.168.10.10:22...
Could not connect to '192.168.10.10' (port 22): Connection failed.
2.2 图形管理工具
如何打开图形管理工具:
图形界面如下:
- 1:Configuration,选择运行时(Runtime)模式或永久(Permanent)模式的配置。
- 2:Zones,可选的策略集合区域列表。
- 3:Services,常用的系统服务列表。
- 4:public,当前正在使用的区域。
- 5:Services,管理当前被选中区域中的服务。
- 6:Ports,管理当前被选中区域中的端口。
- 7:Masquerading,开启或关闭 SNAT(源地址转换协议)技术。
- 8:Port Forwarding,设置端口转发策略。
- 9:ICMP Filter,控制请求 icmp 服务的流量。
- 10:Rich Rules,管理防火墙的富规则。
- 11:interfaces,管理网卡设备。
- 12:被选中区域的服务,若勾选了相应服务前面的复选框,则表示允许与之相关
的流量。 - 13: firewall-config 工具的运行状态。
2.3 服务的访问控制列表
TCP Wrappers 是 RHEL 7 系统中默认启用的一款流量监控程序,它能够根据来访主机的地址
与本机的目标服务程序作出允许或拒绝的操作。
TCP Wrappers 服务的防火墙策略由两个控制列表文件所控制,/etc/hosts.deny和/etc/hosts.allow,系统将会先检查允许控制列表文件(/etc/hosts.allow),如果匹配到相应的允许策略则放行流量; 如果没有匹配,则去进一步匹配拒绝控制列表文件(/etc/hosts.deny),若找到匹配项则拒绝该流量。如果这两个文件全都没有匹配到,则默认放行流量。
建议先编写拒绝策略规则,再编写允许策略规则,以便直观地看到相应的效果。
[root@linuxprobe ~]# vim /etc/hosts.deny
# #
hosts.deny This file contains access rules which are used to
# deny connections to network services that either use
# the tcp_wrappers library or that have been
# started through a tcp_wrappers-enabled xinetd.
# #
The rules in this file can also be set up in
# /etc/hosts.allow with a 'deny' option instead.
# #
See 'man 5 hosts_options' and 'man 5 hosts_access'
# for information on rule syntax.
# See 'man tcpd' for information on tcp_wrappers
sshd:*
[root@linuxprobe ~]# ssh 192.168.10.10
ssh_exchange_identification: read: Connection reset by peer
接下来,在允许策略规则文件中添加一条规则,使其放行源自 192.168.10.0/24 网段,访问本机 sshd 服务的所有流量。可以看到,服务器立刻就放行了访问 sshd 服务的流量,效果非常直观:
[root@linuxprobe ~]# vim /etc/hosts.allow
# #
hosts.allow This file contains access rules which are used to
# allow or deny connections to network services that
# either use the tcp_wrappers library or that have been
# started through a tcp_wrappers-enabled xinetd.
# #
See 'man 5 hosts_options' and 'man 5 hosts_access'
# for information on rule syntax.
# See 'man tcpd' for information on tcp_wrappers
sshd:192.168.10.
[root@linuxprobe ~]# ssh 192.168.10.10
The authenticity of host '192.168.10.10 (192.168.10.10)' can't be established.
ECDSA key fingerprint is 70:3b:5d:37:96:7b:2e:a5:28:0d:7e:dc:47:6a:fe:5c.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.10.10' (ECDSA) to the list of known hosts.
[email protected]'s password:
Last login: Wed May 4 07:56:29 2017
[root@linuxprobe ~]#