linux学习笔记

www.kernel.org经常关注linux内核最新版本和特性

linux:GNU:GNU/Linux,源代码
发行版:Fedora,RedHat(CentOS),SUSE(OPEN SUSE),Debain(Ubuntu,Mint),Gentoo(可自行编译),LFS(Linux From Scratch)

编译:把源代码转换成可以被CPU识别的二进制代码。作用是把源程序转换成你对应平台可以执行的二进制格式的,与硬件密切相关。

RedHat:通用格式的平台编译好的。


此次课程传授:
RHCE+RHCA+shell编程+MySQL+Web集群+NoSQL+Hadoop+Hbase+Openstack

OS:
WINDOWS
LINUX
UNIX
HP-UNIX
SOLARIS
AIX
SCO UNIX
UNIXWARE
OS/2

操作系统的组成:
底层硬件--Kernel内核--library:API(库)--shell--应用

内核功能:
进程管理
内存管理
文件系统
网络功能
硬件驱动
安全机制
。。。

GNU:GNU is Not UNIX
GPL:General Public License,通用公共许可证,版权
Copyright,Copyleft
开源协定
LGPL:lesser
GPLv2
GPLv3

linux基础原则:
1、由目的单一的小程序组成,组合小程序完成复杂任务;
2、一切皆文件;
3、尽量避免捕获用户接口(减少用户交互);
4、配置文件保存为纯文本格式;

GUI接口:
CLI接口:
命令提示符,prompt,bash(shell)
#:root
$:普通用户
命令:

命令格式:
命令 选项
选项:
短选项:-character(单字母)
多个选项可以组合:-a -b = -ab
长选项:--word (一串字符)
参数:命令的作用对象

使用凭证:
root,redhat

虚拟终端(terminal):Ctrl+Alt+F1 ~ F6 可以任意切换终端入口

GUI(图形接口):Graphic User Interface
Gnome:c开发
KDE:C++开发
XFace:简洁的适用于嵌入式平台的简易界面

CLI(命令行接口):Command Line Interface
sh
bash
csh
zsh
ksh
tcsh

默认用户:
root,student,vistor

su:switch user (切换用户)
#su 用户名 半切换
#su -l 用户名 完全切换 选项如果是[-l]的说明可省略的

#passwd 用户名 设置(更改)密码
密码复杂性规则:
10的6次方 (只有数字)
36的6次方 (数字+小写字母)
62的6次方 (数字+小写字母+大写字母)
可以再增加标点符号和特殊字符,复杂性会更高,破解几率变低
1、使用4种类别字符中至少3种;
2、足够长,大于7位;
3、使用随机字符串;
4、定期更换;
5、循环周期足够大;

login:
用户名:用户ID

认证机制:Authentication
授权:Authorization
审计:Audition (日志)

prompt,命令提示符:
命令:
magic number:魔数
shebang
#!/bin/bash

命令使用格式:
#command options... arguments...
选项:修改命令的执行特性
短选项
长选项
参数:指定命令的作用对象

list:ls
列出,列表

目录,文件:路径映射而已,并不是真正文件夹的概念。
路径:从指定起始点到目的地所经过的位置

文件系统:file system

列出指定路径下的所有目录及文件

目录:working directory,current directory

pwd:printing working directory

ls
-l;长格式
文件类型:
-:普通文件(f)
d:目录文件
b:块设备文件(block)
c:字符设备文件(character)
l:符号链接文件(symbolic link file)
p:命令管道文件(pipe)
s:套接字文件(socket)
文件权限:9位,每3位一组,每一组:rwx(读,写,执行),rw-可读写不能执行
文件硬链接的次数
文件的属主(owner)
文件的属组(group)
文件大小(size),默认单位是字节
时间戳(timestamp)这里显示被修改的时间。最近一次被访问的时间,最近一次被修改的时间,最近一次被改变的时间(修改是数据更改,改变是属性更改)
访问:access(文件被访问时间)
修改:modify(文件数据被修改)
改变:change,metadata,(改变文件元数据)
-h:做单位转换(将文件大小显示为更易读的数值)
-a:显示以.开头的隐藏文件
.表示当前目录
..表示父目录
-A:显示隐藏文件但不现实.和..
-d:显示目录自身属性
-i:index node,inode 显示文件的索引节点号
-r:逆序显示文件,默认是顺序显示文件
-R:递归(recursive)显示,子目录下的内容一并显示

cd:change directory
家目录,主目录,home directory
cd ~username:进入指定用户的家目录
cd -:在当前目录和前一次所在的目录之间来回切换

命令类型:
内置命令(shell内置):内部,内建
外部命令:在文件系统的某个路径下有一个与命令名称相应的可执行文件

type:显示指定属于那种类型

环境变量:命名的内存空间(将一块内存空间起个名)
变量赋值:起名之后往这个名称的内存空间里放数据
NAME(空间的命名)=Jerry(放入的数据)

printenv:显示系统中所有环境变量的赋值
如果path路径中同一个命令存在于多个目录,那排在前面的目录中的命令最先执行

hash:键值库。o(1)无论缓存内容多长,同读取1个文件的时间是一样的。
缓存命中了多少次,所有使用过的命令路径。
缓存为王,如果发现系统慢了就加缓存来解决。

date:时间管理

linux:每次重启时从硬件时钟读取时间。叫rtc实时时钟

硬件时钟:主板上的晶体振荡器来计时,非常精确。靠主板纽扣电池来支撑。clock或hwclock查看硬件时间
系统时钟:由操作系统来记录的时间。date看到的是系统时间。

获得命令的使用帮助:
内部命令:
help command
外部命令:
COMMAND --help

命令手册:manual
man COMMAND 比如:man ls

whatis COMMAND
显示命令手册共几个章节,带p的可以忽略,只看纯数字章节数

分章节:常见章节有8个 使用方式:man 1 COMMAND
1、用户命令(/bin,/usr/bin,/usr/loacl/bin)
2、系统调用
3、库调用
4、特殊文件(设备文件)
5、文件格式(配置文件的语法)
6、游戏
7、杂项(miacellaneous)
8、管理命令(/sbin,/usr/sbin/,/usr/loacl/sbin)
man命令中
[]可选
<>必选
...可以使用多次
|:多选一
{}:分组

MAN:
NAME:命令名称及功能简要说明
SYNOPSIS:用法说明,包括可用的选项
DESCRIPRION:命令功能的详尽说明,可能包括每一个选项的意义
OPTIONS:说明每一个选项的意义
FILES:此命令相关的配置文件
BUGS:关于此命令的bug反馈
EXAMPLES:使用示例
SEE ALSO:另外参照

翻屏:
向后翻一屏:SPACE
向前翻一屏:b
向后翻一行:ENTER
先前翻一行:k

查找:
/KEYWORD(查找键值):向后
n:下一个
N:前一个

?KEYWORD(查找键值):向前
n:下一个
N:前一个

q:退出

hwclock
-w:将系统时间同步至硬件时间
-s:将硬件时间同步至系统时间

在线文档:
info COMMAND:命令的历史详情,man的补充

所有帮助文档所在目录:/usr/share/doc
进入查看某个命令的解释

apache,hadoop

cal:calendar日历简写

如何认识echo命令
type echo 提示内部命令
man echo 命令文档
help echo 使用帮助
换行:
echo -e “The year is 2013。\nToday is 26.”
退一格显示:
echo -e “The year is 2013。\bToday is 26.”
退两格
echo -e “The year is 2013。\b \bToday is 26.”
横向制表符,两行之间会空白一段显示
echo -e “The year is 2013。\tToday is 26.”
纵向制表符,上下错开显示
echo -e “The year is 2013。\vToday is 26.”
不换行显示,在命令提示符前显示输出
echo -n “The year is 2013。\nToday is 26.”

printf命令:
不换行显示,在命令提示符前显示输出
printf “The year is 2013”
在命令提示符前显示换行:
printf “The year is 2013。\nToday is 26。”
正常显示
printf “The year is 2013。\nToday is 26。\n”

file命令及其用法:
file /bin/ls
WINDOWS:pe
LINUX:ELF是可执行二进制文件的格式。
查看ls命令相关内容

文件系统
linux目录结构呈树状结构
rootfs:根文件系统 /表示根

FHS:文件系统层级标准,linux发行版必须遵守

/boot:系统启动相关文件。内核、initrd和vmlinuz等关键文件,以及grub(bootloader)。操作系统启动时需要用到的内核和磁盘映像文件initrd
/dev:设备文件。查找设备相关内容。
设备文件:linux中必须有设备文件才可以被访问
块设备:随机访问的设备,数据块
字符设备:线性访问的设备(有次序的),显示器和鼠标等均为字符设备
特殊设备是没有大小的
设备号:主设备号(major)和次设备号(minor)
/etc:配置文件
/home:用户的家目录,每个用户的目录通常默认为/home/USERNAME
/root:root管理员的家目录。
/lib:库文件
静态库:.a
动态库:动态链接文件。.dll,.so(shared object)
/lib/modules:内核模块文件

库:被调用的封装好的功能。执行时直接调用即可。
共享库:内存里加载共享库后,可供多个程序使用。

lost+found:任何一个分区上都会有的目录,跟文件系统相关,是用于存储那些文件系统在机器断电时文件没有输入属租尚未来得及保存的文件,实现丢失找回的。

/media:挂载点目录。设备文件不能直接打开,需要映射给某个目录才能访问。通常用于挂在移动设备。
/mnt:挂在点目录,额外的临时文件系统。
/misc:杂项
/opt:可选目录,早期用于第三方应用软件的。Nessus、oracle等。现在已变更为/usr/local目录下。
/proc:此目录启动前为空,启动后存放内核的映射文件。
/sys:伪文件系统,也是映射文件,跟硬件设备相关的属性映射文件。实现硬盘设备管理。磁盘调度队列再此修改。
/tmp:临时文件。1月内未做文件修改会清空。/var/tmp
/var:可变化的文件存放目录。缓存、锁文件、日志文件等。
/bin:系统自身使用的可执行文件,用户命令
/sbin:系统自身使用的管理命令
/usr:shared,read-only,全局的共享的只读文件。第三方应用程序使用目录
/usr/bin
/usr/sbin
/usr/lib
/usr/loacl:
/usr/loacl/bin
/usr/loacl/sbin
/usr/loacl/lib

命名规则:
1、文件名长度不能超过255个字符;
2、不能使用/当文件名;
3、严格区分大小写

相对路径:相对于当前位置所开始的路径
绝对路径:由根开始的路径

文件管理:创建文件,编辑文件
目录管理:创建目录,切换目录
ls cd pwd
#mkdir:创建空目录
-p:递归式创建目录
-v:verbose详细信息
mkdir -pv /mnt/test/x/m /mnt/test/y
mkdir -pv /mnt/test/{x/m,y}
命令行展开:
/mnt/test2/目录下创建一下目录
a_b,a_c,d_b,d_c
(a+b)(b+c)=ab+ac+db+dc
{a,d}_{b,c}

#tree:查看目录树

删除目录:rmdir(remove directory)
删除空目录
-p

文件创建和删除
touch:用于修改文件的时间戳的。可用于创建文件。
-a:修改访问时间
-m:更改修改时间
-t:自定义更改时间
-c:不改变

stat:显示文件或文件系统的状态信息
[root@localhost ~]# stat install.log
File: `install.log'
Size: 41179 Blocks: 96 IO Block: 4096 regular file
Device: 803h/2051d Inode: 522243 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2018-04-23 11:38:02.352442511 -0700 访问时间
Modify: 2018-04-23 12:00:44.749316659 -0700 修改时间
Change: 2018-04-23 12:01:23.679827233 -0700 改变时间

创建文件,可以使用文件编辑机

ASCII:asck码,美国国家标准信息交换代码

128个不同的字符:
二进制:
2的6次方=0-63
2的7次方=0,127
2的16次方:65536
标准:GB18030,GBK,GB2312,Unicode

linux下的文本编辑器:
nano:简单的编辑器

删除文件:rm 有别名其实是rm -i;\rm去除别名,使用rm本身执行
-i:交互式,删除时会提示用户。
-f:强制删除。
-r:删除目录,递归删除目录下的所有文件

复制和移动文件
cp:copy
cp SRC DEST
cp file1 file2 file3
一个文件到一个文件
多个文件到一个目录
-R -r:递归复制目录及目录下所有文件到目标位置
-i:交互式
-f:强行复制
-p:复制时保留文件原有的属组和属主
-a:归档复制,保留原有所有属性。常用于备份。
-L:不保持链接属性
-P:保持文件原有的链接属性
-d:保持链接属性

mv:move
移动文件

mv SRC DEST
mv -t DEST SRC
在相对路径下直接执行mv一个文件或目录也可以做改名使用
-f:强制覆盖
-i:交互式
-t:现指定目标位置再指定需移动的文件

install:复制文件和设置属性。install的源必须是文件,无法复制目录
-d DIRECOTRY:创建目录
SRC DEST:复制文件,并给予执行权限
-m:可以指定权限
-t:install -t DEST SRC

 

运行程序
设备管理
软件管理
进程管理
网络管理

目录管理:
ls、cd、pwd、mkdir、rmdir、tree

文件管理:
touch、stat、file、rm、cp、mv、nano

日期时间:
date、clock、hwclock、cal(日历)

文本文件管理:
cat、more、less、head、tail、cut、sort、uniq、grep

查看文本:
cat、more、less、head、tail

cat:链接并显示
-n:显示行号
-E:显示每行的行结束符(对于linux的文本文件行结束符是$符,而windows下文本文件行结束符是$+回车。)
-T:制表符,显示控制符号
-v:托字符,行首控制符等特殊符号
-A:显示所有
cat命令反过来tac是文件尾部至首部倒序进行显示。

Ctrl+c终止命令

cat显示内容较多,在终端无法全屏展示,需要Shift+pgup或pgdn来翻页显示,但是由于cat命令是放在缓存当中的,如果文件显示内容过多,也是不能全部显示出来的。

分屏显示:
more、less

more:向后翻。
翻屏:
向后翻一屏:SPACE
向前翻一屏:b
向后翻一行:ENTER

less:与man命令使用类似
翻屏:
向后翻一屏:SPACE
向前翻一屏:b
向后翻一行:ENTER
先前翻一行:k

查找:
/KEYWORD(查找键值):向后
n:下一个
N:前一个

?KEYWORD(查找键值):向前
n:下一个
N:前一个

q:退出

head:查看文件前n行 例:head -n 5 filename
tail:查看文件后n行 例:tail -5 filename
n:默认是10行
-n:可指定显示的行数

tail -f :查看文件尾部,不退出,等待显示后续追加至此文件的新内容。持续显示最新的结尾内容

文本处理:
cut、join、sed、awk

database:数据库
关系型数据库:
表:表中可以没有行但不能没有列。二维表:行和列。列和列之间的分割

文本文件:
Tom:23:male:2013/05/06 (冒号就是分隔符)

cut -d : -f1 /etc/passwd
-d:指定字段分隔符,默认是空格
-f:指定要显示的字段, 显示第几列
-f 1 显示第一列
-f 1,3 显示第一列和第三列
-f 1-3 显示第一列到第三列

文本排序:
sort(默认以升序进行排序)
示例:
[root@localhost ~]# sort /etc/fstab

#
#
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# Created by anaconda on Mon Apr 23 11:38:02 2018
devpts /dev/pts devpts gid=5,mode=620 0 0
# /etc/fstab
proc /proc proc defaults 0 0
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
sysfs /sys sysfs defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
UUID=018f5971-2eec-4c36-9d1a-1ffa87300f9b /boot ext4 defaults 1 2
UUID=a6a649bb-bdde-4e9e-9548-c1e9c5e591e8 / ext4 defaults 1 1
UUID=b3767047-e088-430b-b049-077f90080dd3 swap swap defaults 0 0

使用sort直接排序为asck码排序,会按照字符由左到右依次排序。
-n:数值排序
-r:降序排序(与sort直接使用相反)
-t:字段分隔符
-k:第几个字段排序
-u:去重,相同的行只显示一次
-f:排序时忽略字符大小写
示例:以:为分隔符以第三个字段为准按数字大小进行排序
[root@localhost ~]# sort -t: -k3 -n /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
sync:x:5:0:sync:/sbin:/bin/sync

uniq:相邻的重复行只显示一次
-d:只显示重复的行
-D:显示所有重复的行
-c:把重复行显示出来并显示重复的次数

文本统计:
wc(word count) 统计一个文本文件中所有的行数
-l:只显示行
-w:只显示字符数
-c:只显示字节数
-L:表示最长的那行所包含的字符
示例:
[root@localhost ~]# wc /etc/fstab
15 78 805 /etc/fstab
行数 字符数 字节数

字符处理命令
tr:转换或删除字符
tr [OPTION]... SET1 [SET2]
-d:删除字符

示例1:只要有ab小写的都更换为大写的AB了
[root@localhost ~]# tr 'ab' 'AB'
abc
ABc
Able
ABle
示例2:把某个文件的a-z的小写全部更换为大写
[root@localhost ~]# tr 'a-z' 'A-Z' < /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
SYNC:X:5:0:SYNC:/SBIN:/BIN/SYNC
示例3:只要含a和b的字样全部被删除,输入字符回车后显示删除后的字符串
[root@localhost ~]# tr -d 'ab'
hellodba
hellod
are
re

bash及其特性:
shell特性:外壳
GUI:Gnome,kde,xfce
CLI:sh,csh,ksh,bash(遵循开源特性,涵盖sh,ksh等多种特性),tcsh,zsh(后期出现,功能更加强大)

root,student:两个用户用的是一套shell程序,但打开了两个进程。
程序只有一个
进程可以多个(程序的副本),进程是程序执行的实例。

允许一个用户账号可以打开多次,只是打开了多个进程。
进程:在每个进程看来,当前主机上只存在内核和当前进程,他意识不到其他进程的存在。

shell本身是一个内部命令
[root@localhost ~]# type bash
bash is /bin/bash

用户工作环境:
bash:
# 超级用户
$ 普通用户

shell,子shell
pstree命令可以看到命令shell环境调用关系(进程树)

bash特性:
1、命令历史
2、管道、重定向
3、命令别名
4、命令行编辑
5、命令行展开
6、文件名通配
7、变量
8、编程

命令行编辑:
命令光标跳转:
Ctrl+a:跳到命令行首
Ctrl+e:跳到命令行尾
Ctrl+u:删除光标前至命令行首的内容
Ctrl+k:删除光标前至命令行尾的内容
Ctrl+d:逐字删除光标后的字符
Ctrl+左右箭头:跳到左右一个单词
Ctrl+l:清屏
命令历史:bash会自动记录过去执行过的命令,而且会将其保存在内存的一段缓存区内,使用上下箭头即可找出过去命令
history:查看历史命令
-c:清空整个命令历史
-d OFFSET [n]:删除指定位置的命令历史 例:history -d 500 10 删除从第500条命令之后的10个命令
当用户退出时,系统会将内存内的历史命令保存至用户的家目录下,文件名为.bash_history
-w:将缓冲区命令写入文件中,保存命令历史至历史文件。

环境变量:
PATH:命令搜索路径
HISTSIZE:命令历史缓冲区大小

命令历史的适用技巧:
!n:执行命令历史中的第n条记录。
!-n:执行命令历史中倒数第n条记录
!!:执行上一条命令
!man:执行最近一次执行过的man命令
!string(任意字符串):执行命令历史中最近一个以指定字符串开头的命令
!$:引用前一个命令的最后一个参数。nano !$ 显示nano所创建的文件。
摁一下Esc松开摁.(点)即可
Alt+.也可以

命令补全:
PATH:命令搜索路径
敲命令开头使用Tab键可进行补全,如果有重复会展示出以此开头为首的所有命令

路径补全:
路径补全依旧使用Tabl键补全,而与命令补全机制不同,命令补全在搜索路径下查找,而路径补全是以打头路径下查找。

命令别名:
alias CMDLIAS='COMMAND [options] [arguments]'
在shell中定义的别名仅在当前shell生命周期中有效,别名的作用范围为当前shell进程
例:alias cls=clear
如果希望永久有效,可以将命令写入到bash配置文件中即可
使用alias命令可以看到所有定义别名
alias是shell的内建命令,help alis即可获取使用帮助
ualias cls 撤销别名
\CMD 不使用别名直接执行命令

命令替换:$(COMMAND),反引号:`CONMAND`
把命令中某个子命令替换为其执行结果的过程
例:[root@localhost ~]# echo " The current directory is $(pwd)."
The current directory is /root.

例:[root@localhost ~]# echo "Dir is `pwd`"
Dir is /root

例:[root@localhost ~]# touch ./file-$(date +%F-%H-%M-%S).txt
[root@localhost ~]# ls
anaconda-ks.cfg Documents file file-2018-05-04-07-17-02.txt install.log.syslog Pictures Templates
Desktop Downloads file- install.log Music Public Videos

bash支持的引号:
· ·:命令替换
“ ”:弱引用,可以实现变量替换
' ':强引用,不完成变量替换

文件名通配:globbing
*:匹配任意长度的任意字符
?:匹配任意单个字符
[]:匹配指定范围内的任意单个字符
[abc],[a-m],[a-z],[A-Z],[0-9],[a-zA-Z],[0-9a-zA-Z]


特殊字符匹配:使用时要在外部再加一层[]中括号使用
例:[[:alpha:]]*[[:space:]]*[[:alpha:]] 匹配字母开头字母结尾并中间含空白字符的文件
例:[[:alpha:]]*[[:space:]]*[^[:alpha:]] 匹配字母开头中间空白字符非字母结尾的文件
[:space:]:空白字符
[:punct:]:标点符号
[:lower:]:小写字母
[:upper:]:大写字母
[:alpha:]:大小写字母
[:digit:]:数字
[:alnum:]:数字和大小写字母
man 7 glob 可以查看到特殊字符匹配代码
[^]:托字符,匹配指定范围之外的任意单个字符。例:ls [^0-9]* 匹配非数字开头的文件


用户、组、权限

用户:标识符
用户组:标识符

安全上下文(secure context)
任何时候用户操作计算机无非就是发起进程,因此进程是用户操作计算机的代理,所以进程在运行的时候一定是以发起进程的用户身份来运行的,所以这个进程能够访问那些文件,取决于进程自己的权限以及他访问的资源或文件的权限。

权限:每一类用户都有三种权限
r(读),w(写),x(执行)

文件:
r:可读,可以使用类似cat等命令查看文件内容;
w:可写,可以编辑或删除此文件;
x:可执行,exacutable,可以命令提示符下当作命令提交给内核运行;

目录:
r:可以对此目录执行ls以列出内容的所有文件;
w:可以再次目录中创建文件;
x:可以使用cd切换进此目录,也可以使用ls -l查看内部文件的详细信息;

rwx:
r--:只读
r-x:读和执行
---:无权限
8进制 2进制 权限表示
0 000 ---:无权限
1 001 --x:执行权限
2 010 -w-:写权限
3 011 -wx:写和执行
4 100 r--:只读
5 101 r-x:读和执行
6 110 rw-:读写
7 111 rwx:读写执行

r=4,w=2,x=1

755:rwxr-xr-x
640:rw-r-----
660:rw-rw----
775:rwxrwxr-x

用户:UID,/etc/passwd
组:GID,/etc/group

影子口令:
用户:/etc/shadow
组:/etc/gshadow

用户类别:
管理员:永远为0,内置
普通用户:1-65535
系统用户:1-499
一般用户:500-60000

用户组类别:
管理员组:
普通组:
系统组:
一般组:

用户组类别:
私有组:创建用户时,如果没有为其制定所属的组,系统会自动为其创建一个与用户名同名的组
基本组:用户的默认组
附加组,额外组:默认组意外的其他组

进程:tom tom
对象:rwxrw-r-- jerry tom a.txt
访问请求进入,系统会先核对对象文件的属主权限,如果不是则查看属组权限,还不是核对其他权限

tom:ls
rwxr-xr-x root root /bin/ls

whatis passwd:查看passwd介绍的章节,
[root@localhost ~]# whatis passwd
passwd (1) - update user's authentication tokens 关于passwd命令的使用
passwd (5) - password file 关于passwd文件内容的解释
passwd [sslpasswd] (1ssl) - compute password hashes 关于计算机密码的哈希算法
man 5 passwd:查看第5章节,关于passwd文件内容的解释

passwd文件中显示的内容:
account:登陆用户名
password:密码(暗码x表示)
UID:用户ID
GID:基本组ID
GECOS (comment):一般为空,显示用户注释信息,如:全面、办公地址、办公电话等等。
HOME DIR:家目录
SHELL:用户的默认shell

shadow文件中显示内容:
account:登录名
encrypted password:加密的密码
密码定期更换时长:从1970年1月1日到上一次更换密码的时间的总天数
密码最短使用期限,0表示不限定
密码最长使用期限,0表示无限期
密码还有多久过期向客户发起提醒
在密码不做更改后,还有多少天必须修改密码才能登陆
用户有效期限
保留字段,无含义

加密方法:
对称加密:加密和解密使用同一个密码
公钥加密(非对称加密):每个密码都成对儿出现,一个为私钥(secret key),一个为公钥(public key),并且一个钥匙一把锁
单向加密,散列加密:提取数据特征码,也称指纹加密。常用于数据完整性校验。
1、不可逆,能加密不能解密
2、雪崩效应或蝴蝶效应,初始情况下的微小改变导致后期的巨大改变
例:
[root@localhost ~]# md5sum file-2018-05-04-07-17-02.txt 查看某文件的特征码
d41d8cd98f00b204e9800998ecf8427e(特征码) file-2018-05-04-07-17-02.txt
[root@localhost ~]# vi file-2018-05-04-07-17-02.txt 将文件编辑添加111字段
[root@localhost ~]# md5sum file-2018-05-04-07-17-02.txt 再次查看文件的特征码有了巨大的改变
1181c1834012245d785120e3505ed169(完全不一致的特征码) file-2018-05-04-07-17-02.txt
3、定长输出
MD5:Message Digest 信息摘要,128位定长输出
SHA1:Secure Hash Algorithm,安全哈希加密,160位定长输出。安全级别高,但较慢。
SHA256\SHA512:定长256位和512位的定长输出

useradd:添加用户
which useradd:/usr/sbin/useradd

useradd USERNAME 添加用户
passwd USERNAME 用户设置密码,或更改密码

group文件内容:
组名:
组密码:
组ID:
以此组为附加组的用户列表,额外组,多个组用逗号隔开
groupadd GRPNAME:添加新组

用户管理:
useradd,userdel,usermod,passwd,chsh,chfn,finger,id,chage
组管理:
groupadd,groupdel,groupmod,gpasswd
权限管理:
chown,chgrp,chmod,umask

系统中自带的shell类型
[root@localhost ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh

useradd [options] USERNAME
-u UID 指定UID号,首先普通用户ID号要大于500,并且不能与其他用户ID冲突
-g GID 指定基本组ID号,
-G GID,...(附加组,可以多个组使用逗号隔开)
-c "COMMENT" 指定注释信息
-d /path/to/directory 指定家目录 例:useradd -c “Tony Blare” -d /home/blare user4
-s 指定shell路径,需要指定在/etc/shells:指定了当前系统可用的安全shell 例:useradd -s /sbin/nologin user5
-m -k搭配使用 强行为用户创建家目录
-M 不给用户创建家目录
-r:添加一个系统用户。系统用户无法登陆系统,也没有家目录。

/etc/login.defs 指定用户相关的默认配置

环境变量:
PATH
HISTSIZE
SHELL:用于显示当前用户shell类型

/etc/shells:指定了当前系统可用的安全shell

userdel:
userdel [option] USERNAME
id:默认显示当前用户的ID号信息,后面指定用户就显示指定用户的ID号信息
-u:显示用户ID信息
-g:显示用户所属组ID
-G:显示用户所在组以及附属组ID
-n:显示组或用户名,与-g、-G、-u联合使用
-r:连带用户家目录一起删除


finger:检索用户账号信息的命令
finger USERNAME

修改用户账号属性:
usermod
-u UID:修改账户UID
-g GID:修改账户GID
-G GID:修改附加组GID,慎用。会将原有附加组信息覆盖。搭配-a选项则是添加新的附加组信息。
-c:注释信息,加双引号
-d:指定新的家目录,配合-m使用,将原有家目录下的文件全部移动至新的家目录中
-s:更改用户的shell
-l:为用户改名
-e:定义用户的过期时间,格式YYYY-MM-DD
-f:指定用户的非活动时间,密码过期了但还未禁用的时间段
-L:锁定用户账号,相当于禁用
-U:用于解锁用户账号

chsh:改变用户shell

chfn:修改用户注释信息

密码管理:
passwd USERNAME
--stdin:从标准输入读取密码。例:echo “redhat”|passwd --stdin user3 直接将user3用户密码修改为redhat
-l:锁定用户账号
-u:解锁用户
-n:密码最短使用期限
-x:密码最长使用期限
-w:警告时间
-i:非活动时间(密码过期至用户禁用之间的时间段)
-d:删除用户密码

PAM:与密码属性相关

pwck:检查用户账号完整性

组管理:
创建组:groupadd
-g:指定GID
-r:添加一个系统组

groupmod:修改组的相关属性
-g GID
-n 修改组名

groupdel GRPNAME:删除组

gpasswd GRPNAME:为组加密码

newgrp:登陆到一个新组,临时切换一个新租,这时需要填入组密码。如果从基本组切换到附加组是无需密码的。使用exit退出切换组

chage:改变用户密码过期信息
-d:指定最近一次的修改时间
-E:用户账号的禁用时间
-I:非活动时间
-m:密码最短使用期限
-M:密码最长使用期限
-W:警告时长

权限管理:
r:
w:
x:

三类用户:
u:属主
g:属组
o:其他用户

chown:改变文件属主(只有管理员才可以使用此命令)
# chown USERNAME file,...
-R:修改目录及其内部文件的属主
--reference=/path/to/somefile file,...:引用,参考,跟某个文件的属主和属组改为一样
# chown USERNAME:GRPNAME file,... 改变某个文件的属主和属组
# chown USERNAME.GRPNAME file,... 改变某个文件的属主和属组
# chown :GRPNAME file,... 只改变属组

chgrp:改变文件属组(只有管理员才可以使用此命令)
# chgrp GRPNAME file,...
-R:修改目录及其内部文件的属组
--reference=/path/to/somefile file,...:引用,参考,跟某个文件的属组一样

chmod:改变文件权限(只有管理员才可以使用此命令)
修改三类用户的权限:
chmod MODE(777) file,...
-R:递归修改为此权限
--reference=/path/to/somefile file,...

修改某类用户或某些类用户权限
u,g,o,a
chmod 用户类别=MODE file,...
chmod u=rwx filename
chmod g=r,o=r filename
chmod go=r filename

修改某类的用户某位或某些位权限
u,g,o,a
chmod 用户类别+|-MODE file,...
chmod u-x filename
chmod u+x,g-x filename
chmod a+x filename 全部加执行权限

umask:遮罩码,反向掩码。
创建文件默认权限:666-umask
创建目录默认权限:777-umask

文件默认不能具有执行权限,如果算得的结果中有执行权限,则将其权限加1

管理员umask=022,普通用户umask=002

设置umask码,就用umask 对应数字即可

站在用户角度来讲SHELL的类型:
登陆式shell:
正常通过某终端登陆的shell
su - USERNAME 完全切换
su -l USERNAME

非登陆式shell:
su USERNAME 半切换
图形终端下打开命令窗口
自动执行的shell脚本

bash的配置文件:
全局配置:编辑全局配置文件的任意一个对所有用户都生效
/etc/profile, /etc/profile.d/*sh, /etc/bashrc
个人配置:编辑个人配置,只对个人用户生效
~/.bash_profile, ~/.bashrc

作用范围越小,越是最终生效的,因此个人配置设定优于全局配置。很多配置均遵循此法则
profile类的文件:
设定环境变量
运行命令或脚本:用户登录就执行的命令或脚本

bashrc类的文件:
设定本地变量
定义命令别名

登陆式shell如何读取配置文件?
读取过程:/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc

非登陆式shell如何读取配置文件?
~/.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh

普通用户设定的umask登出之后再登录就恢复默认的,是因为需要在~/.bashrc中加载别名设置,设置好之后在下次登陆时生效。

bash:脚本解释器

运算器+控制器=cpu
存储器:RAM
输入设备/输出设备

程序:指令和数据

控制器:读取指令
运算器:
存储器:

地址总线:内存寻址
数据总线:传输数据
控制总线:控制指令

寄存器:CPU内部的暂时存储器

I/O:硬盘,

程序

INPUT设备:

OUTPUT设备:

系统设定
默认输出设备:标准输出,STDOUT,1
默认输入设备:标准输入,STDIN,0
标准错误输出:STDERR,2

标准输入:键盘
标准输出和错误输出:显示器

I/O重定向:

Linux:
输出重定向:
>:覆盖输出
>>:追加输出

set:设定某些功能开或关,set -C开启此功能,set +C关闭此功能
-C:禁止对已存在文件使用覆盖重定向
在>后面加|可以在开启-C功能时强制覆盖输出
+C:关闭上述功能

2>:重定向错误输出
2>>:追加方式

例:ls /varr > /tmp/var3.out 2> /tmp/err.out 如果命令执行正确输入至/tmp/var3.out如果错误输出至/tmp/err.out

&>:重定向标准输出或错误输出至同一个文件
&>>:追加方式

<:输入重定向
tr字符大小写转换命令举例:
[root@localhost ~]# tr 'a-z' 'A-Z' 把输入的字母都换成大写,此命令会一直等待输入,使用Ctrl+c终止
abc
ABC
sdf
SDF
klj
KLJ
[root@localhost ~]# tr 'a-z' 'A-Z' < /etc/fstab
而使用输入重定向就会将后面的文件直接输出到屏幕并进行字母转换
#
# /ETC/FSTAB
# CREATED BY ANACONDA ON MON APR 23 11:38:02 2018
#
# 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
#
UUID=A6A649BB-BDDE-4E9E-9548-C1E9C5E591E8 / EXT4 DEFAULTS 1 1
UUID=018F5971-2EEC-4C36-9D1A-1FFA87300F9B /BOOT EXT4 DEFAULTS 1 2
UUID=B3767047-E088-430B-B049-077F90080DD3 SWAP SWAP DEFAULTS 0 0
TMPFS /DEV/SHM TMPFS DEFAULTS 0 0
DEVPTS /DEV/PTS DEVPTS GID=5,MODE=620 0 0
SYSFS /SYS SYSFS DEFAULTS 0 0
PROC /PROC PROC DEFAULTS 0 0

<<:Here Document,在此处生成文档
例:使用命令追加结束字符串,在输入完毕后写入此字符自动终止并输出之前输入的所有字符串。终止字符一般为:EOF或END
[root@localhost ~]# cat << END
> The first line.
> The second line.
> END
The first line.
The second line.
例:创建了一个myfile.txt文件,并追加输入了一些自定义内容再EOF结束。
[root@localhost ~]# cat >> /tmp/myfile.txt << EOF
> This is myfiles.
> This is my son.
> EOF
[root@localhost ~]# cat /tmp/myfile.txt 查看此文件是追加输入的内容。
This is myfiles.
This is my son.


管道:前一个命令的输出,当作后一个命令的输入

命令1 | 命令2 | 命令3 | ...

例:
[root@localhost ~]# echo "hello world." | tr 'a-z' 'A-Z' 将标准的hello world换位大写输出
HELLO WORLD.
[root@localhost ~]# echo "redhat" | passwd --stdin hive 将echo输出的字符作为hive用户的密码设定
Changing password for user hive.
passwd: all authentication tokens updated successfully.
[root@localhost ~]# cut -d: -f1 /etc/passwd | sort 将passwd文件的内容第一行进行字母排序
abrt
adm
apache
avahi-autoipd
bin
daemon
dbus
[root@localhost ~]# cut -d: -f3 /etc/passwd | sort -n 对passwd文件的第三列进行数字排序,sort -n为数字排序
0
1
2
3
4
5
6
7

tee:从标准输入读取数据,并且发送至标准输出和文件。一个输入两个输出。
[root@localhost ~]# echo "hello world." | tee /tmp/hello.out
hello world.
[root@localhost ~]# cat /tmp/hello.out
hello world.

显示文件行数:
[root@localhost ~]# wc -l /etc/passwd
33 /etc/passwd

只保留行数:
[root@localhost ~]# wc -l /etc/passwd | cut -d' ' -f1
33

查看文件的前面第一行
ls -l /usr/bin | head -1
total 108020

显示文件的前两行
[root@localhost ~]# ls -l /usr/bin | head -2
total 108020
-rwxr-xr-x. 1 root root 37000 Apr 17 2012 [

显示总行数
[root@localhost ~]# ls -l /usr/bin | wc -l
1274

查出passwd文件中shell登陆信息,并sort -n去掉重复内容
[root@localhost ~]# cut -d: -f7 /etc/passwd | sort -u
/bin/bash
/bin/sync
/sbin/halt
/sbin/nologin
/sbin/shutdown

显示出/var/log下的所有文件类型
[root@localhost ~]# file /var/log/*
/var/log/anaconda.ifcfg.log: ASCII text
/var/log/anaconda.log: ASCII C program text
/var/log/anaconda.program.log: ASCII English text, with very long lines, with overstriking
/var/log/anaconda.storage.log: ASCII C++ program text, with very long lines
/var/log/anaconda.syslog: ASCII English text, with very long lines
/var/log/anaconda.xlog: ASCII English text
/var/log/anaconda.yum.log: ASCII text
/var/log/audit: directory
/var/log/boot.log: ASCII English text, with CRLF, CR line terminators, with escape sequences
/var/log/btmp: empty
/var/log/btmp-20180503: data

取出inittab第6行并显示出最后一行
[root@localhost ~]# head -6 /etc/inittab | tail -1
#

取出passwd文件的倒数第九行,先取出倒数的最后9行在head第一行就是倒数第九行
[root@localhost ~]# tail -9 /etc/passwd | head -1
postfix:x:89:89::/var/spool/postfix:/sbin/nologin

从上面命令的基础上再取出第1列和第7列并显示屏幕和保存到/tmp/users文件中
[root@localhost ~]# tail -9 /etc/passwd | head -1 | cut -d: -f1,7 | tee /tmp/users
postfix:/sbin/nologin
[root@localhost ~]# cat /tmp/users
postfix:/sbin/nologin

统计/etc目录下所有pa开头的文件,此时一定要加-d,如果不加会将目录下所有文件均统计进来,并不是etc下的pa开头文件
[root@localhost ~]# ls -d /etc/pa*|wc -l
5


文本查找的需要
grep,egrep,fgrep
grep:根据一个模式,搜索文本,并将符合模式的文本行显示出来。
Pattern:文本字符和正则表达式的元字符组合而成匹配条件。

grep [options] PATTERN [FILE...]
-i:忽略字符大小写
--color:匹配字符用颜色标记
-v:显示没有被模式匹配到的行
-o:只显示被模式匹配到的字符串

例:[root@localhost ~]# grep 'root' /etc/passwd 查找出passwd文件中含有root字符的行
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

文件名通配:globbing
*:任意长度的任意字符
?:任意单个字符
[]:指定范围内
[^]:指定范围外,托字符

正则表达式:Regular EXPression,REGEXP
元字符:
.:匹配任意单个字符
[]:匹配指定范围内的任意单个字符
[^]:匹配指定范围外的任意单个字符
以下内容并不是匹配指定范围内任意单个字符,因此使用以下匹配需在外面再加一层[]来使用
字符集合:
[:digit:] 数字
[:lower:] 小写字母
[:upper:] 大写字母
[:punct:] 标点符号
[:space:] 空白字符
[:alpha:] 所有字母
[:alnum:] 所有数字和字母

例:
[root@localhost ~]# grep 'r..t' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

匹配次数(贪婪模式:尽可能长的匹配):
*:匹配其前面的字符任意次
a,b,ab,aab,acb,adb,amnb
a*b:可匹配 b,ab,aab 任意次包括0次
a.*b:可匹配ab,aab,acb,adb,amnb a开头b结尾

.*:任意长度的任意字符
\:转意字符
\?:匹配其前面的字符1次或0次
\{m,n\}:匹配其前面的字符至少m次,至多n次
\{1,\}:至少1次
\{0,3\}:最多3次

位置锚定:
^:锚定行首,此字符后面的任意内容必须出现在行首
$:锚定行尾,此字符前面的任意内容必须出现在行尾
^$:空白行
\<或\b:锚定词首,其后面的任意字符必须作为单词首部出现 例:grep “\<root” test2.txt 在test2文件中root词首的字符
\>或\b:锚定词尾,其前面的任意字符必须作为单词尾部出现 例:grep “root\>” test2.txt 在test2文件中root结尾的字符

分组:
\(\)
\(ab\)*:ab可以出现0次1次或任意次
后向引用,后面可以引用前面出现过的字符
\1:引用第1个左括号以及与之对应的右括号所包括的所有内容
\2:引用第2个左括号以及与之对应的右括号所包括的所有内容
\3:引用第3个左括号以及与之对应的右括号所包括的所有内容
例:grep '\(l..e\).*\1' test3.txt 前面匹配的是什么后面就必须引用什么,必须一致

[root@localhost etc]# grep '\([0-9]\).*\1$' /etc/fstab 前面出现过的数字结尾有引用1次的显示出来
# Created by anaconda on Mon Apr 23 11:38:02 2018
UUID=a6a649bb-bdde-4e9e-9548-c1e9c5e591e8 / ext4 defaults 1 1
UUID=018f5971-2eec-4c36-9d1a-1ffa87300f9b /boot ext4 defaults 1 2
UUID=b3767047-e088-430b-b049-077f90080dd3 swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0

REGEXP:REGular EXPression
Pattern:

正则表达式:
Basic REGEXP:基本正则表达式
Extended REGEXP:扩展正则表达式

基本正则表达式:
.:任意单个字符
[]:指定范围内的任意单个字符
[^]:指定范围外的任意单个字符

次数匹配:
*:任意次
\?:匹配其前面的字符0或1次
\{m,n\}:匹配其前面的字符至少M次之多N次

.*:任意长度的任意字符

锚定:
^:锚定行首
$:锚定行尾
\<,\b:锚定词首
\>,\b:锚定词尾

\(\):分组
\1,\2,\3,...

grep:使用基本正则表达式定义的模式来过滤文本的命令
-i:忽略大小写
-v:反向匹配
-o:只显示匹配到的字符串
--color:匹配字符用颜色标记
-E:使用扩展的正则表达式
-A N:显示匹配行以及其后面的N行
-B N:显示匹配行以及其前面的N行
-C N:显示匹配行以及其前后面各N行

扩展的正则表达式:
字符匹配:
.:任意单个字符
[]:指定范围内的任意单个字符
[^]:指定范围外的任意单个字符

次数匹配:
*:任意次
?:匹配其前面的字符0或1次
+:匹配其前面的字符至少1次
{m,n}:匹配其前面的字符至少M次之多N次

锚定字符:
^:锚定行首
$:锚定行尾
\<,\b:锚定词首
\>,\b:锚定词尾

分组:扩展正则表达式真正实现了分组
():分组
\1,\2,\3,...

或者:
|:或者 or的意思。例:a|b 表示a或者b
C|cat:表示C或cat,匹配的是首字母
(C|c)at:表示Cat或cat,分组使用

grep -E = egrep 使用egrep直接支持扩展正则表达式

匹配IP地址:ifconfig | egrep -o '\<([0-9]|[1-9]|[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>\.\<([0-9]|[1-9]|[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>\.\<([0-9]|[1-9]|[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>\.\<([0-9]|[1-9]|[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>'

或者改为简写的:ifconfig | egrep --color -o '(\<([0-9]|[1-9]|[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>\.){3}\<([0-9]|[1-9]|[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>'

IPv4:
分5类:A B C D E
A:1-127
B:128-191
C:192-223

准确找出IP地址:
ifconfig | egrep --color -o '(\<[1-9]|[1-9][0-9]|1[0-9]{2}|2[01][0-9]|22[0-3]\>)(\.\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\>){2}\.\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\>'

grep,egrep,fgrep :grep在搜索过程中会大量的消耗CPU使用周期,相当消耗时间。
fgrep:fast grep 快速grep,不支持正则表达式,任何结果都被匹配为原生字符。


shell 编程:

bash:进程变量,进程结束变量就结束

编译器:解释器

编程语言:机器语言、汇编语言、高级语言

编程能力:
脚本编程

静态语言:编译型语言
强类型(变量)
事先转换成可执行格式
C、C++、JAVA、C#
解释器一般均为静态语言开发

动态语言:解释型语言,on the fly,需要脚本解释器,例如:bash
弱类型:
边解释边执行
ASP、ASP.NET、PHP、SHELL、python、perl

面向过程:Shell,C
面向对象:JAVA,python,perl,C++

变量:内存空间,命令内存空间

内存:编址的存储单元

进程:指令和数据都在内存中,存取过程就需要变量

变量名称:
1、只能包含字母、数字、下划线,并且不能数字开头;
2、不应该跟系统中已有的环境变量重名;
3、最好做到见名知义;

变量类型:事先确定数据的存储格式和长度
字符型
数值型
整型:整数
浮点型:带小数点的
真、假型:

逻辑:
逻辑运算:与、或、非、异或
1:真
0:假
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
1 & 1 = 1
与:
只有两者为真才得真,只要有一者为假均为假
或:
只要有一个为真就为真,结果一定为真
非:
!真 = 假
!假 = 真
异或:
操作数相同则为0,否则为1
1和1异或得0
0和0异或得0

整型,8bit:256
0-255,溢出 超出预先设定好的变量阈值,避免溢出与变量阈值进行对比,超出拒绝

shell:弱类型编程语言

强:变量在使用前,必须事先声明,甚至还需要初始化;
NULL:空
弱:变量用时声明,甚至不区分类型;

隐式转换:换算为ASCII码进行运算
显式转换:指定为转换为某种格式
11+c=

变量赋值:VAR_NAME=VALUE

bash变量类型:
环境变量
本地变量(局部变量)
位置变量
特殊变量

引用变量:${VARNAME},括号可以省略;变量名称后加内容的情况下产生混淆的变量需要将变量名称用花括号括起来使用

本地变量:
本地:VARNAME=VALUE:作用域:整个bash进程
局部:local VARNAME=VALUE 作用域为当前代码段

环境变量:作用域为当前shell进程及其子进程;
export VARNAME=VALUE
先VARNAME=VALUE再export VARNAME也可以
“导出”

脚本在执行时会启动一个子shell进程;
命令行中启动的脚本会继承当前shell环境变量
系统自动执行脚本(非命令行启动)就需要自我定义需要各环境变量

位置变量:
$1,$2,...

特殊变量:
$?:上一个命令的执行状态返回值

程序执行后,会产生两类返回值:
程序执行结果
程序状态返回代码:(0-255)
0:正确执行
1-255:错误执行,1,2,127系统预留;其余可自定义

输出重定向:
>:覆盖重定向
>>:追加重定向
2>:错误重定向
2>>:错误追加重定向
&>:同时重定向

/dev/null:软件设备(模拟设备),bit bucket 位同 ,数据黑洞

撤销变量:
unset VARNAME 无需加$符,撤销变量里的值才需要加$

查看当前shell中的变量:
set (环境变量和本地变量)

查看环境变量:
printenv
env
export

变量值增加:
[root@localhost ~]# ANIMALS=pig 设置一个值为pig的ANIMALS的变量
[root@localhost ~]# ANIMALS=$ANIMALS:goat 增加一个goat值
[root@localhost ~]# echo $ANIMALS 增加成功
pig:goat
[root@localhost ~]# ANIMALS=$ANIMALS:sheep 再增加一个sheep值
[root@localhost ~]# echo $ANIMALS 增加成功
pig:goat:sheep

脚本:命令的堆砌,按照实际需要,结合命令流程控制机制实现的源程序

脚本的第一行必须是shebang:魔数;如果不写这行脚本会被认成ASCII码
#!/bin/bash
# 注释行;不执行,标注

如果不给脚本执行权限,可以指定某个脚本解释器来执行
bash first.sh 也可以不赋权执行脚本

练习:
useradd user1
echo "user1" | passwd --stdin user1 &> /dev/null
echo "Add user1 successfully."

条件判断:
如果用户不存在
添加用户,给密码并显示添加成功;
否则
显示如果已经存在,没有添加;

bash中如何实现条件判断?
条件判断类型:
1、整数测试:数值之间的对比
2、字符测试:字符串对比是否正确
3、文件测试:判断文件是否存在等

条件测试的表达式:expression表达式
[ expression ]
[[ expression]]
test expression

整数比较:
-eq:等值比较,测试两个整数是否相等,比如 $A -eq $B
-ne:不等值比较,测试两个整数是否不等,不等,为真;相等,为假;
-gt:测试一个数是否大于另一个数;大于,为真;否则为假;
-lt:测试一个数是否小于另一个数;小于,为真;否则为假;
-ge:大于或等于
-le:小于或等于

命令间的逻辑关系:
逻辑与:&& 其中一个为假结果为假
第一个条件为假时,第二条件不用判断,最终结果已有
第一个条件为真时,第二条件必须得判断
逻辑或:|| 其中一个为真结果为真
第一个条件为假时,第二条件必须判断
第一个条件为真时,第二条件不用判断

例:如果用户存在,就显示用户已存在;否则,就添加此用户;
id user1 && echo "user1 exists." || useradd user1

如果用户不存在,就添加;否则,显示其已经存在;
! id user1 && useradd user1 || echo "user1 exists."

如果用户不存在,添加并且给密码;否则,显示其已经存在;
! id user1 && useradd user1 && echo "user1" | passwd --stdin user1 || echo "user1 exists."

例:添加3个用户user1..3,但要先判断用户是否已存在,不存在而后再添加,最后显示系统共有多少用户
[root@localhost ~]# cat adduser.sh
#!/bin/bash
! id user1 &> /dev/null && useradd user1 && echo "user1" | passwd --stdin user1 &> /dev/null || echo "echo user1 exists."
! id user2 &> /dev/null && useradd user2 && echo "user2" | passwd --stdin user2 &> /dev/null || echo "echo user2 exists."
! id user3 &> /dev/null && useradd user3 && echo "user3" | passwd --stdin user3 &> /dev/null || echo "echo user3 exists."

USERS=`wc -l /etc/passwd | cut -d: -f1`
echo "$USERS users."

条件判断,控制结构:

单分支的if语句
if 判断条件; then
statement1
statement2
...
fi

双分支的if语句
if 判断条件; then
statement1
statement2
...
else
statement3
statement4
...
fi

多分支的if语句
if 判断条件1; then
statement1
...
elif 判断条件2; then
statement2
...
elif 判断条件3; then
statement3
...
else
statement4
...
fi


例:如果用户存在则输出用户存在字样,否则创建并配置密码输出用户添加完成
[root@localhost ~]# cat usertest.sh
#!/bin/bash
#
NAME=user17

if id $NAME &> /dev/null; then
echo "$NAME exist."
else
useradd $NAME
echo $NAME | passwd --stdin $NAME &> /dev/null
echo "Add $NAME finished"
fi
[root@localhost ~]# ./usertest.sh
Add user17 finished
[root@localhost ~]# ./usertest.sh
user17 exist.

练习:写一个脚本
判断当前系统上是否有用户的默认shell为bash;
如果有,就显示有多少个这类用户;否则就显示没有这类用户;
#!/bin/bash
#
grep "bash$" /etc/passwd &> /dev/null
RETVAL=$?
if [ $RETVAL -eq 0 ];then
USERS=`grep "\<bash$" /etc/passwd |wc -l`
echo "The shells of $USERS users is bash."
else
echo "NO such user."
fi

提示:“引用”一个命令的执行结果,要使用命令引用;比如:RESAULTS=`wc -l /etc/passwd | cut -d: -f1`;
使用一个命令的执行状态结果,要直接执行此命令,一定不能引用;比如:if id user1 一居中的id命令就一定不能加引号;
如果想把一个命令的执行结果赋值给某变量,要使用命令引用,比如USERID=`id -u uder1`; 如果想把一个命令的执行状态结果保存下来,并作为命令执行成功与否的判断条件,则需要先执行命令,而后引用其状态结果,如:
id -u user1
RETVAL=$?
此句绝对不可以写为RETVAL=`id -u user1`;

[root@localhost ~]# cat bash2.sh
#!/bin/bash
#
grep "bash$" /etc/passwd &> /dev/null
RETVAL=$?
if [ $RETVAL -eq 0 ];then
AUSER=`grep "\<bash$" /etc/passwd |head -1|cut -d: -f1`
echo "$AUSER is one of such users."
else
echo "NO such user."

脚本:给定一个用户,判断其UID和GID是否一样,如果一样,就显示此用户为“good guy”;否则就显示此用户为“bad guy”

#!/bin/bash
#
USERNAME=user1
USERID=`id -u $USERNAME`
GROUPID=`id -g $USERNAME`
if [ $USERID -eq $GROUPID ];then
echo "Good guy"
else
echo "Bad guy."
fi

脚本:给定一个用户,获取其密码警告期限;而后判断用户最近一次修改密码时间距其最长使用期限是否已经小于警告期限;
提示:算术运算的方法$[$A-$B];表示变量A的值减去变量B的值的结果;
如果小于,则显示“Warning”;否则,就显示“OK”。

 

脚本:判定命令历史中历史命令的总条目是否大于1000;如果大于,则显示“Some command will gone.”;否则显示“OK”。
#!/bin/bash
#
HISTORY=`history | tail -l |cut -d' ' -f2`
if [ $HISTORY -gt 1000];then
echo "Some command will gone."
else
echo "OK"
fi



shell中如何进行算术运算:
1、let 算术运算表达式
let C=$A+$B
2、$[算术运算表达式]
C=$[$A+$B]
3、$((算术运算表达式))
C=$(($A+$B))
4、expr 算术运算表达式,表达式中各操作数及运算符之间要有空格,而且要使用命令引用
C=`expr $A + $B`
前三种最为常见

圆整:丢弃小数点后的所有内容

脚本:当前用户的密码是否已经小于警告期限
[root@localhost ~]# vi passwdtime.sh
You have new mail in /var/spool/mail/root
[root@localhost ~]# cat passwdtime.sh
#!/bin/bash
#
W=`grep "student" /etc/shadow | cut -d: -f6` #取出Worning的时长
S=`date +%s` #取得1970年至此刻经过的秒数
T=`expr $S/86400` #计算到今天的时长
L=`grep "^student" /etc/shadow | cut -d: -f5` #密码最长使用期限
N=`grep "^student" /etc/shadow | cut -d: -f3` #最近一次修改密码的时间
SY=$[$L-$[$T-$N]] #计算剩余时间

if [ $SY -lt $W ]; then #用使用时间与Worning时间比较
echo 'Worning'
else
echo 'OK'
fi


[root@localhost ~]# TIMESTAMP=`date +%s` 获取1970年到当前的天数
[root@localhost ~]# let USEDAYS=$TIMESTAMP/86400 计算今天的时间是 除以86400
[root@localhost ~]# echo $USEDAYS 输出到今天的使用期限
17667

exit:退出脚本。某个步骤结果得出后无需后面的执行则使用exit退出脚本
例:不适用id命令判定user1用户的userID和groupID是否一致。
[root@localhost ~]# cat testID.sh
#!/bin/bash
#
USERNAME=user1
if ! grep "^$USERNAME\>" /etc/passwd &> /dev/null; then #找到用户是否存在于系统,!为假,返回真结果的反义
echo "No such user:$USERNAME."
exit 1 #如果没有此用户可以直接退出脚本,1为错误代码,0为正确1-255均为错误
fi
USERID=`grep "^$USERNAME\>" /etc/passwd |cut -d: -f3`
GROUPID=`grep "^$USERNAME\>" /etc/passwd |cut -d: -f4`
if [ $USERID -eq $GROUPID ]; then
echo "Good guy."
else
echo "Bad guy."
fi


bash中常用的条件测试有三种:

测试方法:
[ expression ]
[[ expression ]]
test expression

整数测试:
-gt:测试一个数是否大于另一个数;大于,为真;否则为假;
-le:小于或等于
-ne:不等值比较,测试两个整数是否不等,不等,为真;相等,为假;
-eq:等值比较,测试两个整数是否相等,比如
-ge:大于或等于
-lt:测试一个数是否小于另一个数;小于,为真;否则为假;

INT1=63
INT2=77
[ $INT1 -eq $INT2 ]
[[ $INT1 -eq $INT2 ]]
test $INT1 -eq $INT2

文件测试:
-e FILE:测试文件是否存在
-f FILE:测试文件是否为普通文件
-d FILE:测试指定路径是否为目录
-r FILE:测试当前用户对指定文件是否有读权限
-w FILE:测试当前用户对指定文件是否有写权限
-x FILE:测试当前用户对指定文件是否有执行权限

[ -e /etc/inittab ] 测试文件是否存在
[ ! -e /etc/inittab ] 测试文件不存在,加!取反义
[ -x /etc/inittab ] 测试当前用户对此文件是否有执行权

文件是否存在脚本:

[root@localhost ~]# cat filetest.sh
#!/bin/bash
#
FILE=/etc/inittab

if [ -e $FILE ]; then
echo "OK"
else
echo "No such file."
fi

脚本是否有语法错误:
bash -n filetest.sh
bash -x 脚本:单步执行
[root@localhost ~]# bash -x filetest.sh
+ FILE=/etc/inittab
+ '[' -e /etc/inittab ']'
+ echo OK
OK

练习:
脚本:给定一个文件,如果是普通文件,就显示普通文件,如果是目录,也显示目录,否则,此为无法识别文件;
[root@localhost ~]# cat filetest2.sh
#!/bin/bash
#
FILE=/etc/rc.d/rc.sysinit

if [ ! -e $FILE ]; then
echo "No such file."
exit 6
fi

if [ -f $FILE ]; then
echo "Common file."
elif [ -d $FILE ]; then
echo "Directory."
else
echo "Unknown."
fi

定义脚本退出状态码
exit:退出脚本。
exit #
如果脚本没有明确定义退出状态码,那么,最后执行的一条命令的退出码即为脚本的退出状态码。

bash变量的类型:
本地变量(局部变量) 作用域当前shell进程
环境变量 作用域为当前shell进程及其子进程;
位置变量:
$1,$2,...
shift(轮换,替换)把$1剔除,$2变为$1
例:
[root@localhost ~]# cat shift.sh
#!/bin/bash
#

echo $1
shift
echo $1
shift
echo $1
[root@localhost ~]# ./shift.sh 1 2 3
1
2
3

例:
./filetest.sh中 /etc/fstab /etc/inittab
$1表示 /etc/fstab
$2表示 /etc/inittab
特殊变量
$?:上一条名令的退出状态码
$#:参数的个数
$*:参数列表
$@:参数列表

脚本:能接受一个参数(文件路径),判定:此参数如果是一个存在的文件,就显示“OK”;否则就显示“No such file.”
[root@localhost ~]# cat filetest3.sh
#!/bin/bash
#
if [ $# -lt 1 ]; then
echo "Usage:./filetest3.sh ARG1 [ARG2 ...]"
exit 7
fi

if [ -e $1 ]; then
echo "OK."
else
echo "No such file."
fi

练习:脚本
给脚本传递两个参数(整数);显示此两者之和,之积
[root@localhost ~]# cat calc.sh
#!/bin/bash
#
if [ $# -lt 2 ];then
echo "Usage: cacl.sh ARG1 ARG2"
exit 8
fi

echo "The sum is:$[$1+$2]."
echo "The prod is:$[$1*$2]."
结果:
[root@localhost ~]# ./calc.sh 2 5
The sum is:7.
The prod is:10.

grep,sed(流编辑器),awk
sed基本用法:
sed:Stream EDitor;
行编辑器(全屏编辑器:vi)

sed:模式空间,内嵌模式条件,模式匹配-->处理-->输出显示。
默认不编辑原文件,仅对模式空间中的数据做处理;而后,处理结束后,将模式空间打印至屏幕;
sed处理流程:sed将文本文件的每一行读进模式空间与模式条件进行匹配,匹配后用其编辑命令进行编辑并显示出来

sed命令使用格式:
sed [options] 'AddressCommand' file ... 对file中的某些行(Address)进行编辑处理
-n:静默模式。不再默认显示模式空间中的内容
-i:直接修改原文件,危险操作
-e SCRIPT -e SCRIPT:可以同时执行多个脚本
-f /PATH/TO/SED_SCRIPT:将多个执行脚本的一行保存至此文件中
sed -f /path/to/scripts file
-r:表示使用扩展正则表达式


Address:
1、StartLine,EndLine
比如:1,100表示1-100行
$:最后一行
$-1:倒数第二行
2、/RegExp/
比如:/^root/ 使用正则表达式表示行,root开头的行
3、/pattern1/,/pattern2/
第一次被模式1匹配到的行开始至第一次被模式2匹配到的行结束
4、LineNumber
指定的行
5、StartLine,+N
从指定行开始,向后的N行;

Command:
d:删除符合条件的行;
例:sed '1,2d' /etc/fstab 删除fstab文件的前两行
sed '3,$d' /etc/fstab 删除fstab文件的第三行到最后一行
sed '/oot/d' /etc/fstab 删除fstab文件中含有oot字符的行
sed '1,+2d' /etc/fstab 删除fstab文件的第1行向后2行,共删除3行
p:显示符合条件的行;
例:sed -n '/^\//p' /etc/fstab 符合条件的显示出两行,没符合的显示一次,加-n不显示空间模式的内容,只显示符合条件内容
a \string:在指定的行后面追加新行,内容为“string”
例:sed '/^\//a \# hello world' /etc/fstab 在/开头的行后面追加一行# hello world
sed '/^\//a \# hello world\n hello,linux' /etc/fstab 在/开头的行后面追加两行内容,\n为换行符
i \string:在指定的行前面追加新行,内容为“string”
例:sed '/^\//i \# hello world' /etc/fstab 在/开头的行前面追加一行# hello world
r FILENAME:将指定的文件的内容添加至符合条件的行处
例:sed '2r /etc/issue' /etc/fstab 将issue文件内容加入到fstab中的第二行开始显示
sed '1,2r /etc/issue' /etc/fstab 将issue文件内容加入到fstab中的第1行和第2行都显示
w FILENAME:将地址指定范围内的内容另存至指定的文件中;
例:sed '/oot/w /tmp/oot.txt' /etc/fstab 将fstab文件中含有oot字符的行保存至/tmp/oot.txt文件中
s/pattern/string/:查找并替换,默认只替换每行中第一次被匹配到的字符串;查找内容pattern可以使用正则表达式元字符,替换内容string不可以;
加修饰符改变默认匹配模式
g:全局替换
i:查找时忽略字符大小写
例:sed 's/oot/OOT/' /etc/fstab 将fstab下oot的字符全部替换为大写的OOT
sed 's/\//#/' /etc/fstab 将文件中含有/的全部替换为# 默认只匹配了每一行第一次匹配到的字符串一行中有两个/的第二次的字符串未被匹配替换。
sed 's/\//#/g' /etc/fstab 后面加g将全文中的/全部替换为#
s///将/做分隔符,也可以为s###以#为分隔符,也可以s@@@以@为分隔符
例:sed 's#oot#OOT#' /etc/fstab
sed 's@oot@OOT@' /etc/fstab
练习:
l..e:like-->liker
love-->lover
sed 's#l..e#&r#g' sed.txt 因为后面替换内容无法使用正则表达式,因此使用&字符表示匹配到的内容
sed 's#\(l..e\)#\1r#g' sed.txt 也可以写为此方式,表示将前面括号内容定义为1次匹配进行添加,后向引用
将l换为L:
sed 's#l#L#g' sed.txt
sed 's#l\(..e\)#L\1#g' sed.txt
history |sed 's#^[[:space:]]*##g' 将history前面无论多少空格全部替换为空

sed练习:
1、删除/etc/grub.conf文件中行首的空白符;
sed -r 's@^[[:space:]]+@@g' /etc/grub.conf
2、替换/etc/inittab文件中“id:3:initdefault:”一行中的数字为5:;
sed 's@\(id:\)[0-9]\(:initdefault:\)@\15\2@g' /etc/inittab
3、删除/etc/inittab文件中的空白行;
sed '/^$/d' /etc/inittab
4、删除/etc/inittab文件中开头的#号;
sed 's@^#@@g' /etc/inittab
5、删除某文件中开头的#号及后面的空白字符,但要求#号后面必须有空白字符;
sed -r 's@^#[[:space:]]+@@g' /etc/inittab
6、删除某文件中以空白字符后面跟#类的航中的开头的空白字符及#
sed -r 's@^[[:space:]]+#@@g' /etc/inittab
7、取出一个文件路径的目录名称;
echo "/etc/rc.d/"|sed -r 's@^(/.*/)[^/]+/?@\1@g'
基名:


字符测试:
==:测试是否相当,相当为真,不等为假
!= :测试是否不等,不等为真,等则为假
>:
<:
-n string:测试指定字符串是否为空,空则真,不空则假
-z string:测试指定字符串是否不空,不空为真,空则为假

例:取用户的userID和groupID是否一样
#!/bin/bash
#
if [ `id -n -u $1` == `id -n -g $1` ]; then
echo "Yiyang"
else
echo "Bu Yiyang"
fi

例:传递个参数,按照q、Q、Quit、quit即便退出否则输出用户参数
[root@localhost ~]# cat testid.sh
#!/bin/bash
#
if [ $1 = 'q' ]; then
echo "Quiting..."
exit 1
elif [ $1 = 'Q' ];then
echo "Quiting..."
exit 2
elif [ $1 = 'quit' ];then
echo "Quiting..."
exit 3
elif [ $1 = 'Quit' ];then
echo "Quiting..."
exit 4
else
echo $1
fi

例:传递三个参数给脚本,第一个为整数,第二个为算术运算符,第三个为整数,将计算结果显示出来,要求保留两位精度。如:./calc.sh 5 / 2
[root@localhost ~]# cat calc1.sh
#!/bin/bash
#
echo "scale=2;$1$2$3;" | bc
[root@localhost ~]# ./calc1.sh 5 / 2
2.50

计算方式,精度计算.scale=2为精度计算方式,;号为命令分隔符
echo "scale=2;111/22;" | bc
或者:
bc <<< "scale=2;111/22;"

循环:进入条件,退出条件
1、for循环
2、while循环
3、until循环

for 变量 in 列表
do
循环体
done

for I in 1 2 3 4 5 6 7 8 9 10; do
加法运算
done

当列表被遍历完成之后退出;

如何生成列表:
{1..100}

seq:数值序列,指定数字范围
使用方法:
seq 起始数 步进长度 结束数
[root@localhost ~]# seq 10
1
2
3
4
5
6
7
8
9
10
[root@localhost ~]# seq 5 10
5
6
7
8
9
10
[root@localhost ~]# seq 2 2 10
2
4
6
8
10
[root@localhost ~]# seq 1 2 10
1
3
5
7
9

declare -i SUM=0 将一个变量声明为整数
integer
-x:将一个变量声明为环境变量

例:1循环加一直加到100结果是多少?
[root@localhost ~]# cat sum.sh
#!/bin/bash
#
declare -i SUM=0

for I in {1..100}; do
let SUM=$[$SUM+$I]
done

echo "The sum is: $SUM."
[root@localhost ~]# ./sum.sh
The sum is: 5050.

例:取出每一个用户,向用户问候Hello
[root@localhost ~]# LINES=`wc -l /etc/passwd|cut -d' ' -f1`
[root@localhost ~]# for I in `seq 1 $LINES`; do echo "Hello `head -n $I /etc/passwd|tail -1|cut -d: -f1`"; done
Hello root
Hello bin
Hello daemon
Hello adm
Hello lp
Hello sync
Hello shutdown
Hello halt
Hello mail
Hello uucp
Hello operator
Hello games
Hello gopher
Hello ftp

取模,取余:%
3%2=1
100%55=45

vim编辑器:

文本编辑器,字处理器
ASCII

nano,sed

vi:Visual Interface 可视化接口,体积小,但功能强大
vim:VI iMproved vi的增强版,在vi基础上增加了增强功能的插件

全屏编辑器,模式化编辑器

vim模式:
编辑模式(命令模式)
输入模式
末行模式

模式转换:
编辑-->输入:
i:在当前光标所在字符的前面,转为输入模式;
a:在当前光标所在字符的后面,转为输入模式;
o:在当前光标所在行的下方,新建一行,并转为输入模式;
I:在当前光标所在行的行首,转换为输入模式;
A:在当前光标所在行的行尾,转换为输入模式;
O:在当前光标所在行的上方,新建一行,并转为输入模式;

输入-->编辑:
ESC键:输入返回编辑模式

编辑-->末行:
:(冒号)既可以转为末行模式,末行模式需要输入命令
:10d 删除第10行
:10,20d 删除10至20行
:set nu 显示行号

末行-->编辑:
ESC键
某些情况下需敲两次ESC切换模式

一、打开文件
#vim /path/to/somefile
vim +N行号 file:打开文件时定位于第N行
vim + file:打开文件定位于最后一行
vim +/pattern:打开文件,定位至第一次被pattern匹配到的行行首

默认打开文件时处于编辑模式

二、关闭文件
1、末行模式关闭文件
w:保存
w!:强行保存,只有管理员有此权限
q:不保存退出
wq或x:保存并退出
q!:不保存强行退出
2、编辑模式下退出
ZZ:大写模式敲两次ZZ直接保存退出

三、移动光标
1、逐字符移动:
h:向左,前加数字N表示向左移动N位
l:向右,前加数字N表示向右移动N位
j:向下,前加数字N表示向下移动N位
k:向上,前加数字N表示向上移动N位

2、以单词为单位移动:
w:移至下一个单词的词首,前加数字表示移动移至下N个单词词首
e:跳至当前或下一个单词词尾,前加数字表示移动移至下N个单词词尾
b:跳至当前或前一个单词词首,前加数字表示移动移至前N个单词词首

3、行内跳转:
0或^:表示跳到行首,0跳到绝对行首,^行首的第一个非空白字符
$:表示跳到行尾,$绝对行尾;

4、行间跳转:
#G:直接跳转至第#行;
G:最后一行

末行模式下,直接给出行号回车即可

四、翻屏
Ctrl+f:向下翻一屏
Ctrl+b:向上翻一屏
Ctrl+d:向下翻半屏
Ctrl+u:向上翻半屏

五、删除单个字符
x:删除光标所在处的单个字符,在x前加数字可连续删除N个字符

六、删除命令:d
d命令跟跳转命令组合使用
d$:光标所在处到行尾全部删除
d^或d0:光标所在处到行首全部删除
dw:光标所在处的单词删除
#d跳转符:删除跳转符的#个,通常使用#dw、#de、#db
dd:删除当前光标所在行
#dd:删除包括光标所在行在内的#行

末行模式下:
起始行,终止行d
.:表示当前行
$:最后一行
+#:向下的#行
$-10 表示倒数第10行,
例:
:.,$-3d 表示从光标所在行删除到倒数第三行
:1,8d 表示删除第1行到第8行
:.,+5d 表示从光标所在行向下再删除5行
:.,100d 表示当前行到第100行删除

vim所删除的内容不会立即被清空,可实现找回,还可实现剪切

七、粘贴命令:p
P:大写P,如果删除或复制为整行内容,则粘贴至光标所在行的下方,如果复制或删除的内容为非整行,否则粘贴至光标所在字符的后面
p:小写p,如果删除或复制为整行内容,则粘贴至光标所在行的上方,如果复制或删除的内容为非整行,否则粘贴至光标所在字符的前面

八、复制命令:y
用法同d命令
yy:复制一行
#yy:复制#行

九、修改:先删除内容再转回为输入模式:
c:用法同d命令
cc:删除某行并转换为输入模式
c$:在光标所在处至行尾删除,并转换为输入模式

十、替换:r
替换单个字符:r+替换字符
R:替换模式,直接敲击内容输入并将现有内容替换

十一、撤销编辑操作:u
u:撤销前一次的编辑操作,连续u可以连续撤销此前的n次操作,默认最多撤销前50次的操作
#u:直接撤销#次编辑操作

还原最近一次撤销操作:Ctrl+r

十二、重复前一次的编辑操作:.
.:直接摁点可重复上次操作

十三、可视化模式:VISUAL
v或V均可进入可视化模式
v:按字符选取
V:按矩形选取

十四、查找:
/PATTERN:从文件首部到尾部查找某PATTERN
?PATTERN:从光标所在位置向文件首部查找
n:下一个匹配到的内容
N:上一个匹配到的内容

十五、查找并替换
在末行模式下
起始地址,终止地址s/PATTERN/PATTERN/g 全局替换
起始地址,终止地址s/PATTERN/PATTERN/i 忽略大小写
例:
:.,$-1s/he/HE/g 替换当前行到倒数第2行的he替换为HE,在范围内全局替换
%:表示全文范围

练习:将/etc/yum.repos.d/server.repo文件中的ftp://instructor.example.com/pub替换为http://172.16.0.1/yum

:%s/ftp:\/\/instructor\.example\.com\/pub/http:\/\/172.16.0.1\/yum/g
:%s@ftp:\/\/instructor\.example\.com\/pub@http://172.16.0.1/yum@g

十六、使用vim编辑多个文件
vim file1 file2 默认打开为第一个文件
切换第二个文件在末行模式下
:next 切换至下一个文件
:prev 切换至前一个文件
:last 切换至最后一个文件
:first 切换至第一个文件

:qa 全部退出,只输入q只退出当前文件

十七、分屏显示一个文件:
Ctrl+w,松开w再摁s键 :水平拆分窗口
Ctrl+w,松开再摁v键 :垂直拆分窗口

在窗口间切换光标:
Ctrl+w,上下箭头ARROW键

:qa 全部退出,只输入q只退出当前窗口

十八、分窗口编辑多个文件
vim -o :水平分割显示
vim -O :垂直分割显示

十九、将当前文件的部分内容另存为另一个文件
末行模式下使用w命令
:w 保存
:ADDR1,ADDR2w /path/to/somewhere

二十、将另外一个文件内容填充在当前文件中
:r /path/to/somefile

二十一、与shell交互
:! COMMAND

二十二、高级话题
1、显示或取消显示行号
:set number
:set nu 也可简写
取消显示
:set nonu
2、显示忽略或区分字符大小写
:set ignorecase
:set ic
取消忽略大小写
:set noic
3、设定自动缩进
:set autoindent
:set ai
取消自动缩进
:set noai

4、查找到的文本高亮显示
:set hlsearch
取消高亮显示
:set nohlsearch

5、语法高亮
:syntax on
取消语法高亮
:syntax off

二十三、vim配置文件
全局:/etc/vimrc
当前用户:~/.vimrc

vim命令学习导航vimtutor命令

练习:
1、添加10个用户user1到user10,密码同用户名,但要求只有用户不存在的情况下才能添加;
[root@localhost ~]# cat adduser1.sh
#!/bin/bash
#

for i in {1..10}; do
if id user$i &> /dev/null; then
echo "user$i exists."
else
useradd user$i
echo user$i |psasswd --stdin user$i &> /dev/null
echo "Add user user$i finished."
fi
done

2、删除10个用户
[root@localhost ~]# cat deluser.sh
#!/bin/bash
#

for i in {1..10}; do
if id user$i &>/dev/null;then
userdel -r user$i
echo "Delete user$i finished"
else
echo "user$i not exist."
fi
done

3、用户给的参数是add就添加10个用户,如果给的是del就删除10个用户,其他则退出
[root@localhost ~]# cat adminusers.sh
#!/bin/bash
#

if [ $# -lt 1 ]; then
echo "Usage:adminusers ARG"
exit 7
fi

if [ $1 == 'add' ]; then
for i in {1..10}; do
if id user$i &> /dev/null;then
echo "user$i exists."
else
useradd user$i
echo user$i | passwd --stdin user$i &> /dev/null
echo "Add user$i finished."
fi
done
elif [ $1 == 'del' ]; then
for i in {1..10}; do
if id user$i &> /dev/null;then
userdel -r user$i
echo "Delete user$i finished."
else
echo "No user$i."
fi
done
else
echo "Unkown ARG"
exit 8
fi

4、adminusers user1,user2,user3,hello,hi 用adminusers当命令 后面加一堆用户名参数
[root@localhost ~]# cat adminusers2.sh
#!/bin/bash
#

echo $1
for i in `echo $1 |sed 's/,/ /g'`; do
if id $i &> /dev/null;then
echo "$i exists."
else
useradd $i
echo $i |passwd --stdin $i &> /dev/null
echo "add $i finished."
fi
done
执行结果:
[root@localhost ~]# ./adminusers2.sh user1,user2,hi,hello
user1,user2,hi,hello
user1 exists.
user2 exists.
add hi finished.
add hello finished.

如果加--add添加这些用户,如果加--del选项删除这些用户
[root@localhost ~]# cat adminusers2.sh
#!/bin/bash
#
if [ $1 == '--add' ]; then
for i in `echo $2 |sed 's/,/ /g'`; do
if id $i &> /dev/null;then
echo "$i exists."
else
useradd $i
echo $i |passwd --stdin $i &> /dev/null
echo "add $i finished."
fi
done
elif [ $1 == '--del' ]; then
for i in `echo $2 |sed 's/,/ /g'`; do
if id $i &> /dev/null;then
userdel -r $i
echo "Delete $i finished."
else
echo "$i NOT exist."
fi
done
else
echo "Unkown options."
fi

测试:
整数测试
-le:小于或等于
-lt:测试一个数是否小于另一个数;小于,为真;否则为假;
-ge:大于或等于
-gt:测试一个数是否大于另一个数;大于,为真;否则为假;
-eq:等值比较,测试两个整数是否相等,比如
-ne:不等值比较,测试两个整数是否不等,不等,为真;相等,为假;
字符测试
==
!=
>
<
-n
-z
文件测试
-e
-f
-d
-r
-w
-x

if [ $# -gt 1 ]; then

组合测试条件
-a:与关系
-o:或关系
!:非关系

if [ $# -gt 1 -a $# -le 3 ]; then
if [ $# -gt 1 ] && [ $# -le 3 ]; then

脚本1:
输入q,Q,quit,Quit参数就退出

[root@localhost ~]# cat quit.sh
#!/bin/bash
#
if [ $1 == 'q' -o $1 == 'Q' -o $1 == 'quit' -o $1 == 'Quit' ]; then
echo "Quiting ..."
exit 0
else
echo "Unkown Argument."
exit 1
fi

让一个变量加上某个数值之后再重新保存回原有变量空间
let I=$[$I+1]
SUM=$[$SUM+$I]
let SUM+=$I
let I+=1
简化写法 let I++
例如:
[root@localhost ~]# let I+=1
[root@localhost ~]# echo $I
11
[root@localhost ~]# let I+=1
[root@localhost ~]# echo $I
12
简写I++
[root@localhost ~]# let I++
[root@localhost ~]# echo $I
13
[root@localhost ~]# let I++
[root@localhost ~]# echo $I
14
[root@localhost ~]# let I++
[root@localhost ~]# echo $I
15

+=:一个变量在他基础上加另外一个数,只有加1,才可以写成++
let I+=1 相当于 let I++
-=:一个变量在他基础上减去另外一个数
let I-=1 相当于 let I--
++I,--I
*=:一个变量在他基础上乘以另外一个数
/=:一个变量在他基础上除以另外一个数
%=:一个变量在他基础上取模另外一个数

例:使用脚本求出1-100数字中奇数的和与偶数的和

#!/bin/bash
#
declare -i ENENSUM=0
declare -i ODDSUM=0

for i in {1..100}; do
if [ $[$i%2] -eq 0 ]; then
let EVENSUM+=$i
else
let ODDSUM+=$i
fi
done

echo "Odd sum is:$ODDSUM."
echo "Even sum is:$EVENSUM."
执行结果:
[root@localhost ~]# ./showsum.sh
Odd sum is:2500.
Even sum is:2550.

grep,egrep,fgrep:文本查找

文件查找:
locate:
非实时,模糊匹配,查找是根据全系统文件数据库完成;优势,查找速度较快
# updatedb:手动生成文件数据库,运行时间非常长

find:
实时查找,精确匹配,通过遍历指定目录中的所有文件来进行查找,所以速度较慢;支持众多查找标准;

find 查找路径 查找标准 查找到以后的处理动作
查找路径:默认为当前目录
查找标准:默认为指定路径下的所有文件
处理动作:默认为显示至屏幕

匹配标准:
-name ‘FILENAME’:对文件名作精确匹配
文件名通配:
*:任意长度的任意字符
?:单个字符
[]:范围
-iname ‘FILENAME’:文件名匹配不区分大小写
-regex PATTERN:基于正则表达式进行文件名匹配
-user USERNAME:根据文件的属主进行文件名匹配
-group GROUPNAME:根据属组查找文件
-uid UID:根据UID查找 因为用户一旦被删除,搜索用户无法匹配到文件,但继承原有的UID或GID,使用ID号依旧可以查到用户原来所属的文件
-gid GID:根据GID查找
-nouser:查找无属主用户的文件,用户被删除的文件
-nogroup:查找无属组的文件
-type:
f:普通文件
d:目录
c:字符设备
b:块设备
l:链接文件
p:管道设备
s:套接字文件(socket)
-size:粗略匹配,接近某个数值的文件均显示为某个值;例如:10M的文件,9M左右的均会被匹配出来
#k:[+|-] +大于#k的文件,-为小于#k的文件
#M
#G

组合条件:
-a:与条件
-o:或条件
-not:非

不是目录,并且还不能套接字类型的文件:
find /tmp -not -type d -a -not -type s
/tmp/test目录下既不是user1属主也不是user2属主的文件
find . -not -user user1 -a -not -user user2
find . -not \( -user user1 -o -user user2 \)
属主不是user1类型也不是目录的
find . -not -user user1 -o -not -type d
find . -not \( -user user1 -a -type d \)

根据时间戳查找文件:
-mtime:修改时间
-ctime:改变时间
-atime:访问时间
[+|-]#: -#表示#天之内被访问过,+#至少#天没有访问过,#表示正好#天被访问过
-mmin
-cmin
-amin
[+|-]#:-#表示#分钟之内被访问过,+#至少#分钟没有访问过,#表示正好#分钟被访问过

-perm MODE:根据权限来查找文件
mode:
-mode:文件权限能完全包含此MODE时才能显示
/mode:任意一位匹配即满足条件

动作:
-print:显示
-ls:类似ls -l的形式显示每一个文件的详细信息
-ok COMMAND {} \:{}表示前面找到的文件,表示每一个操作都需要用户确认
-exec COMMAND {} \:{}表示前面找到的文件,直接执行不需要确认
例如:find ./ -perm -006 -exec chmod o-w {} \;
find ./ -type d -ok chmod +x {} \;
find ./ -perm -020 -exec mv {} {}.new \; 只要命令中需要引用文件名就使用{}
find ./ -name "*.sh" -a -perm -111 -exec chmod o-x {} \; 将当前目录下sh结尾的有执行权限的文件的其他用户组全部去掉执行权限

练习:
1、查找/var目录下属主为root并且属组为mail的所有文件;
find /var -user root -group mail

2、查找/usr目录下不属于root,bin或student的文件;
find /usr -not -user root -a -not -user bin -a -not -user student
find /usr -not \( -user root -o -user bin -o -user student \)

3、查找/etc目录下最近一周内内容修改过且不属于root及student用户的文件;
find /etc -mtime -7 -not \( -user root -o -user student \)
find /etc -mtime -7 -not -user root -a -not -user student

4、查找当前系统上没有属主或属组且最近1天内曾被访问过的文件,并将其属主属组均修改为root;
find / \(-nouser -o -nogroup \) -a -atime -1 -exec chown root:root {} \;

5、查找/etc目录下大于1M的文件,并将其文件名写入/tmp/etc.largefiles文件中;
find /etc -size 1M >> /tmp/etc.largefiles

6、查找/etc目录下所有用户都没有写权限的文件,显示出其详细信息;
find /etc -not -perm /222 -ls

xarge:从标准输入接受命令并执行的

例:find /etc -size +1M |xargs echo {} >> /tmp/etc.largefiles
与find /etc -size +1M -exec echo {} >> /tmp/etc.largefiles \;不同xargs是空格隔开,exec以行隔开

特殊权限:
passwd:s

SUID:运行某程序时,相应进程的属主是程序文件自身的属主,而不是启动者;
chmod u+s FILE
chmod u-s FILE 取消SUID
如果file本身原来就有执行权限,则SUID显示为s;否则显示为S;
SGID:运行某程序时,相应进程的属组是程序文件自身的属组,而不是启动者所属的基本组;
chmod g+s FILE
chmod g-s FILE 取消SGID
develop team,hadoop,hbase,hive 将三个用户的附加组设定为develop
/tmp/project/
Sticky:在一个公共目录,每个人都可以创建文件,删除自己的文件,但不能删除别人的文件;
chmod o+t DIRECOTRY
chmod o-t DIRECOTRY

000:表示无特殊权限
001:表示有Sticky权限
110:表示有SUID和SGID权限
111:全部特殊权限

chmod 1755 /backup/test 目录有755的权限,并且有Sticky权限
3755 目录有755的权限,表示有SGID权限和Sticky
2755 目录有755的权限,表示有SGID权限
5755 目录有755的权限,表示有SUID权限和Sticky

1表示Sticky
2表示SGID
4表示SUID

umask 0022


文件系统访问控制列表
tom建立的文件,想让jerry可以读写此文件
tom:
属于tom用户和tom基本组
jerry:属于other用户权限,other给rw权限又增加了安全风险
属于jerry用户和tom附加组

FACL:Filesystem Access Control List
利用文件扩展属性,保存额外的访问控制权限

无facl访问次序:Owner-->group-->Other
facl访问次序:Owner-->facl,user-->group-->facl,group-->Other

如果某个文件有访问控制权限的话权限行后有+号
[root@localhost backup]# ll
total 8
-rw-rwxr--+ 1 root root 884 May 25 23:35 inittab

setfacl:设置facl
-m:设定
u:UID:germ
setfacl -m u:hadoop:rw inittab
setfacl -m d:u:hadoop:rw donray 为某个目录以及内容赋权控制列表,前面加d
g:GID:germ
setfacl -m g:mygourp:rw inittab
setfacl -m d:g:mygourp:rw inittab
-x:取消
例:[root@localhost backup]# setfacl -x u:hadoop inittab
[root@localhost backup]# setfacl -x g:mygroup inittab

getfacl:获取facl
例:
[root@localhost backup]# getfacl inittab
# file: inittab
# owner: root
# group: root
user::rw-
user:hadoop:rw-
group::r--
mask::rw-
other::r--

umask:现有权限减去所有权得出的反向结果
mask:无论给访问控制列表中用户和组任何权限都不可超出mask的权限
例:由下可见mask的权限是根据用户指定的权限而更改的,除非我们给mask先设定一个固定权限
[root@localhost backup]# setfacl -m u:hbase:rwx inittab
[root@localhost backup]# getfacl inittab
# file: inittab
# owner: root
# group: root
user::rw-
user:hadoop:rw-
user:hbase:rwx
group::r--
group:mygroup:rw-
mask::rwx
other::r--

mask赋权:setfacl -m mask::rw- inittab
[root@localhost backup]# setfacl -m mask::rw- inittab
[root@localhost backup]# getfacl inittab
# file: inittab
# owner: root
# group: root
user::rw-
user:hbase:rwx #effective:rw-
group::r--
mask::rw-
other::r--

常用命令:
w:显示系统当前登录信息以及正在做的事情
who:显示登录到当前系统上的用户都有哪些,su的切换用户并不是登录用户,所以su的用户who看不到
-r:显示当前运行级别
-H:显示标题信息
例:每隔5秒检查hadoop是否已经登录,如登录,显示已登录,并退出。
sleep:让程序延迟一段时间

 


whoami:当前登录到系统的用户是谁
last:显示用户登录历史及系统重启历史。对应文件:/var/log/wtmp
-n #:显示最近#次的相关信息
lastb:显示用户错误的登录尝试。对应文件:/var/log/btmp
-n #:显示最近#次的相关信息
lastlog:显示每个用户最近一次的成功登录信息。对应文件:/var/log/
-u USERNAME:显示特定用户最近的登录信息

basename:文件基名
$0:指脚本或命令本身
basename $0:输出脚本名称本身
mail:查看邮件,输入mail直接进入邮件信息
选择1回车就是第一封邮件
-s:指定标题
例:[root@localhost backup]# cat /etc/fstab | mail -s "How are you?" root
[root@localhost backup]# mail -s "How are you?" root < /etc/fstab
发送一个fstab内容的邮件给root主题为How are you
hostname:显示当前主机的主机名
例:如果主机名不是www.magedu.com那就改为此
[ `hostname` != 'www.magedu.com' ] && hostname www.magedu.com
例:如果当前主机名为空或localhost,就将其改为www.magedu.com
[ -z `hostname` -o `hostname` == '(none)' -o `hostname` == 'localhost' ] && hostname www.magdu.com

生成随机数
RANDOM:0-32768
echo $RANDOM 随机生成数
随机数生成器:熵池
/dev/random:到熵池中取随机数,如果熵池内无随机数,会提示敲击键盘生成更多随机数
/dev/urandom:熵池中没随机数后,会模拟生成更多随机数

练习:写个脚本,利用RANDOM生成10个随机数,并找出其中的最大值和最小值;
for i in {1..10}; do echo -n "$RANDOM,";echo -e "\n"; done
[root@localhost ~]# cat random.sh
#!/bin/bash
#
declare -i MAX=0
declare -i MIN=0
for i in {1..10};do
MYRAND=$RANDOM
[ $i -eq 1 ] && MIN=$MYRAND
if [ $i -le 9 ]; then
echo -n "$MYRAND,"
else
echo "$MYRAND"
fi
[ $MYRAND -gt $MAX ] && MAX=$MYRAND
[ $MYRAND -lt $MIN ] && MIN=$MYRAND
done

echo $MAX
echo $MIN

终端类型:
console:控制台
pty:物理终端(VGA)
tty#:虚拟控制台(VGA)
ttys#:串行终端
pts/#:伪终端

case:
面向过程:Shell,C
控制结构:
顺序结构
选择结构
循环结构

选择结构:
if:单分支、双分支、多分支
if 测试条件; then
statement1
...
fi

if CONDITION; then
statenment
...
else
statenment
...
fi

if CONDITION1; then
statenment
...
elif CONDITION2; then
statenment
...
esle
statnment
...
fi

case语句:选择结构

case SWITCH(变量值) in
value1)
statenment
...
;;
valuel2)
statement
...
;;
*)
statement
...
;;
esac
例1:
[root@localhost ~]# cat case.sh
#!/bin/bash
#
case $1 in
[0-9])
echo "A digit." ;;
[a-z])
echo "Lower." ;;
[A-Z])
echo "Upper." ;;
*)
echo "Special character.";;
例2:
[root@localhost ~]# cat service.sh
#!/bin/bash
#
case $1 in
'start')
echo "start server ..." ;;
'stop')
echo "stop server ...";;
'restart')
echo "Restarting server ...";;
'status')
echo "Running ...";;
*)
echo "`basename $0` (start|stop|restart|status)";;
esac
例3:
[root@localhost ~]# cat debug.sh
#!/bin/bash
#
case $1 in
-v|--verbose)
DEBUG=1;;
*)
echo "Unknown options"
exit 7
;;
esac

[ $DEBUG == '1' ] && echo hello
例4:
[root@localhost ~]# cat addusercase.sh
#!/bin/bash
#
DEBUG=0

case $1 in
-v|--verbose)
DEBUG=1
;;
esac

useradd tom &> /dev/null
[ $DEBUG -eq 1 ] && echo "Add user tom finished."
例5:可接受选项参数,而后能获取每个选项,及选项的参数;并能够根据选项及参数做出待定的操作
例如:adminuser1.sh --dd USER_LIST --del USER_LIST -v|--verbose -h|--help
[root@localhost ~]# cat adminuser1.sh
#!/bin/bash
#
DEBUG=0
ADD=0
DEL=0

for i in `seq 1 $#`; do
if [ $# -gt 0 ]; then
case $1 in
-v|--verbose)
DEBUG=1
shift ;;
-h|--help)
echo "Usage:`basename $0` --add USER_LIST --del USER_LIST -v|--verbose -h|--help"
exit 0
;;
--add)
ADD=1
ADDUSERS=$2
shift 2
;;
--del)
DEL=1
DELUSERS=$2
shift 2
;;
*)
echo "Usage:`basename $0` --add USER_LIST --del USER_LIST -v|--verbose -h|--help"
exit 7
;;
esac
fi
done

if [ $ADD -eq 1 ]; then
for USER in `echo $ADDUSERS | sed 's@,@ @g'`; do
if id $USER &> /dev/null; then
[ $DEBUG -eq 1 ] && echo "$USER exists."
else
useradd $USER
[ $DEBUG -eq 1 ] && echo "Add user $USER finished."
fi
done
fi

if [ $DEL -eq 1 ]; then
for USER in `echo $DELUSERS | sed 's@,@ @g'`; do
if id $USER &> /dev/null; then
userdel -r $USER
[ $DEBUG -eq 1 ] && echo "Delete user $USER finished."
else
[ $DEBUG -eq 1 ] && echo "$USER not exists."
fi
done
fi
结果:
[root@localhost ~]# ./adminuser1.sh -v --add tom,jerry,natasha
Add user tom finished.
Add user jerry finished.
Add user natasha finished.
[root@localhost ~]# ./adminuser1.sh -v --del tom,jerry,natasha
Delete user tom finished.
Delete user jerry finished.
Delete user natasha finished.
[root@localhost ~]# ./adminuser1.sh -v --add tom,jerry,natasha
Add user tom finished.
Add user jerry finished.
Add user natasha finished.
[root@localhost ~]# ./adminuser1.sh -v --add tom,jerry,natasha
tom exists.
jerry exists.
natasha exists.
例6:写showlogged.sh脚本,-h选项只能单独使用,显示帮助信息;-c选项,显示当前系统登录的所有用户;如果同时使用-v选项,则既显示登录用户又显示用户相关信息:
[root@localhost ~]# cat showlogged.sh
#!/bin/bash
#
declare -i DEBUG=0
declare -i SHOWNUM=0
declare -i SHOWUSERS=0

for i in `seq 1 $#`; do
if [ $# -gt 0 ]; then
case $1 in
-h|--help)
echo "Usage:`basename $0` -h|--help -c|--counts -v|--verbose."
exit 0;;
-v|--verbose)
let SHOWUSERS=1
shift ;;
-c|--count)
let SHOWNUM=1
shift ;;
*)
echo "Usage:`basename $0` -h|--help -c|--counts -v|--verbose."
exit 8;;
esac
fi
done

if [ $SHOWNUM -eq 1 ]; then
echo "Logged users:`who |wc -l`."
if [ $SHOWUSERS -eq 1 ]; then
echo "They are:"
who
fi
fi
结果:
[root@localhost ~]# ./showlogged.sh -h
Usage:showlogged.sh -h|--help -c|--counts -v|--verbose.
[root@localhost ~]# ./showlogged.sh --help
Usage:showlogged.sh -h|--help -c|--counts -v|--verbose.
[root@localhost ~]# echo $?
0
[root@localhost ~]# ./showlogged.sh --hel
Usage:showlogged.sh -h|--help -c|--counts -v|--verbose.
[root@localhost ~]# echo $?
8
[root@localhost ~]# ./showlogged.sh -c
Logged users:1.
[root@localhost ~]# ./showlogged.sh --count
Logged users:1.
[root@localhost ~]# ./showlogged.sh -c -v
Logged users:1.
[root@localhost ~]# vim showlogged.sh
[root@localhost ~]# ./showlogged.sh -c -v
Logged users:1.
They are:
root pts/0 2018-05-29 23:22 (192.168.219.1)

 

磁盘管理:

机械式硬盘RAM:
U盘,光盘,软盘,硬盘,磁带

磁盘按照柱面进行分区
越外层的磁道读写速率越快

分区:partition
创建独立的文件系统
MBR(master boot record)主引导记录:
整个磁盘的0磁道0扇面0 占用512byte,是不会被占用的
前446byte:BootLoader,引导加载器,一段程序,完成引导某个分区将操作系统启动
接下来的64byte:
每16个byte标识一个分区,共划分4个主分区
最后2byte:magic number
标记MBR是否有效
启动过程:
首先内存加载BIOS内容,检验成功后
再加载BootLoader,根据BootLoader内容加载操作系统起始分区,BIOS退出内存
之后再读取64bytes的分区表
BootLoader会找到系统的内核所在位,并将内核加载入内存中
之后BootLoader将工作交给内核,内核再加载系统启动

主+扩展≤4
扩展分区:几十上百都可以创建

文件系统:文件存储的管理程序,存储着data和metadata
data:数据存储
Metadata:元数据,查找文件的索引数据。

分区划分之初会划分多个块组(block group),而创建块组时也会创建对应的块组列表索引,对用户不可见。

每个分区的块组中又含有块位图和iNode位图
bitmap块位图:元数据中含有块位图,每个数据块标记一个图位,0为空磁盘块,1为非空块。加速查找磁盘块。
iNode:index node 索引节点,放置iNode号码以及对应的文件的属主、属组、权限、时间戳、文件大小等等

如果查找/var/log/messages文件
会先从iNode索引中找到/目录,找到/对应的磁盘块,/的磁盘块中又存着自己的索引,从中找到对应的var文件的iNode号,再回到iNode索引中找到对应的磁盘块,找到log对应的iNode号,再依次找到messages的iNode号再找到它所在的磁盘块最终找到对应messages文件

dentry:磁盘块对应的索引中含有一个目录项。

创建一个文件的过程:
在/backup/目录下创建test.txt文件,文件大小为10k,假设每个磁盘块为2k
首先扫描iNode表位图,找到空闲iNode占用此号,找到对应的磁盘块位图,建立test.txt文件名并写入对应的iNode号,再从块位图中找到空闲磁盘块,依次写入此test.txt的10k容量的文件内容。

删除文件的过程:
找到文件,将其目录对应的条目删除,在iNode位图中将此iNode的号标记为空即可,其占据的磁盘块也标记为空。但内部数据未清除,只是再次写入时会把原有数据覆盖掉。所以删除的数据可以找回。

复制与剪切文件的过程:
复制文件的过程,相当于创建文件的过程,而同分区剪切文件只是改变索引位图的路径位置而已,但是跨分区就会相对慢了。跨分区剪切过程在新分区建立新文件,然后再将老分区的文件复制到新分区中,再到老分区中删除原文件。

链接文件:
硬链接:直接指向同一个iNode的不同路径的文件叫做硬链接文件。权限后面跟的数字为此文件硬链接的次数。
符号链接:指向的并不是iNode号而是对应实文件的字符个数。


ls -i:显示文件的iNode号

ln [-s -v] SRC DEST
-s:创建软连接
例:创建硬链接
ln abc test/abc2
再ls -l就可以看到权限后面的数字改变为2了
创建软连接
ln -sv /backup/abc /backup/test/abc2

硬链接:
1、只能对文件创建,不能应用于目录;防止循环链接。
2、不能跨文件系统;iNode号不能跨区域
3、创建硬链接会增加文件被链接的次数

符号链接:
1、可应用于目录
2、可以跨文件系统
3、不会增加被链接文件的链接次数
4、其大小为指定的路径所包含的字符个数;

du:显示文件所占用的磁盘空间大小
-s:显示本目录空间大小
-h:按单位换算显示目录下所有文件大小

df:显示整个磁盘使用分区的使用情况
-h:按单位换算显分区占用大小
-i:可用iNode数量
-P:在同一行内显示,不换行

块设备:不占用磁盘空间,主次设备号存储在iNode当中
b:按块为单位,随机访问的设备;如:硬盘
字符设备:
c:按字符为单位,线性设备;如:键盘

/dev目录下:
中间的10,60的数字代表:指主设备号和次设备号
crw-rw----. 1 root root 10, 60 Jun 7 23:24 network_latency
crw-rw----. 1 root root 10, 59 Jun 7 23:24 network_throughput
crw-rw-rw-. 1 root root 1, 3 Jun 7 23:24 null
主设备号(majar number):
标识设备类型
次设备号(minor number):
标识同一种类型中不同设备

设备文件是作为设备的访问入口的
mknod:创建块或字符文件命令
mknod [option]... name type [major minor]
-p:管道
-m:MODE创建时指定权限
例:
mknod mydev c 66 0
mknod -m 640 mydev2 c 66 1

硬盘设备的设备文件名:
IDE,ATA:hd
SATA:sd
SCSI:sd
USB:sd
a,b,c,...来区别同一种类型下的不同设备

IDE:
第一个IDE口;主hda、从hdb
第二个IDE口:主hdc、从hdd

SCSI、SATA:
sda,sdb,sdc,...

hda:
hda1:第一个主分区
hda2:
hda3:
hda4:
hda5:第一个逻辑分区
主分区最多4个,扩展分区最多1个,逻辑分区可多个

fdisk -l 查看磁盘中所有逻辑分区
fdisk -l [/dev/to/some_device_file]查看某个磁盘设备

低级格式化:创建磁道;厂商出厂便做好的无需自行格式化;
高级格式化:创建文件系统 mkfs -t ext3
vfs:virtual filesystem 负责解释对接各种不同文件系统的编译,linux特有
windows文件系统:FAT32、NTFS;网络层文件系统:CIFS 网上邻居互访
光盘:ISO9660
Linux:ext2、ext3、ext4、xfs、reiserfs、jfs、swap;网络层文件系统:nfs、ocfs2、gfs2

管理磁盘分区:
fdisk /dev/sda 为sda磁盘进行分区
p:显示当前硬件的分区,包括没保存的改动
n:创建新分区
e:扩展分区
p:主分区
d:删除一个分区
w:保存退出
q:不保存退出
t:修改分区类型
L:与l相同
l:显示所支持的所有类型

分区保存后只是设备分区并未被内核识别
cat /proc/partitions可以查看到所有内核识别的分区
partprobe命令使内核重读分区表,此时新分区才能被格式化;红帽5之前的命令,红帽6变换新命令partx

vfs:virtual filesystem 主要是统一不同文件系统调用接口,才能够在linux下使用不同的文件系统
内核通过接口interface:通过system call与硬件进行交互
使用硬盘的磁盘空间就需要系统调用,跟内核申请调用磁盘空间
用户模式与用户空间
内核模式与内核空间
cpu运行通过4个环进行
最内侧为ring 0 内核使用,具备特权
用户进程使用ring 3,无特权

通过iNode:index node找到对应块
格式化后的磁盘缺少了很多空间就是为iNode空间预留了
每8k磁盘空间预留1个iNode,块大小为2的N次方;
block size:1024字节:1k、2048字节:2k、4096字节:4k

内存中的空间的单元被称之为页框,一个页框可存储1个块,2个块或4个块,页框大小一般为4k

bitmap块位图:元数据中含有块位图,每个数据块标记一个图位,0为空磁盘块,1为非空块。加速查找磁盘块。
iNode bitmap inode位图;
block bitmap块位图;
super block超级块:记录整个分区的全局信息,可以有多个备份
1、记录多少块组
2、每个块组中包含多少块
3、块大小
4、空闲磁盘块,已用磁盘块,空闲iNode,已用iNode
块组描述符表:标识块组的起始结束等标识符

整个磁盘空间划分:
boot block:预留引导块,如果按照操作系统,boot loader就安装在此。与MBR不同MBR是个扇区,512k
双系统安装,第一个系统引导安装在MBR中第二个系统引导boot loader就会安装在boot block中存放
block group:块组
super block:超级块,每个块组一个
GDT:块组描述符表,存放当前分区每块组的块组名以及起始和结束的块信息,有多组备份;
block bitmap:块位图,存储块位值信息
iNode bitmap:iNode位图,iNode对应信息
iNode table:iNode存放表
data blocks:数据块

磁盘查找文件顺序:
1、iNode表中找到根的iNode,找到对应的磁盘块
2、根据磁盘块再找到var对应的iNode再通过iNode找到对应磁盘块,在此找到log对应的iNode号
3、再回到iNode表中查log所在块,进入log所在块内所在的messages文件所对应iNode号
4、再回到iNode表查messages所在的磁盘块

目录:
每个目录其实存放的就是一张iNode号和文件名称的对应关系表
第一列存放iNode的号
第三列存放文件名称的长度
第四列文件类型
最后是文件名
iNode格式:内部有直接磁盘块引用格式,间接以及二级格式,使用逐层的引用格式进行块位存储。有直接指针,间接指针以及二级指针等
mode:权限
owner info:属组属主
size:大小
timestamps:时间戳
direct blocks:直接指针
indirect blocks:间接指针
double indirect:二级间接磁盘块指针
triple indirect:三级间接磁盘块指针

ext3:ext2的修复过程非常慢,出现异常时,如果想寻回之前操作必须通过遍历的过程才能找到损坏位
journal file system:日志文件系统
分区中会多建立一份日志区,iNode在日志区创建,数据存储过程中断电可以直接检查日志区的操作,日志区的存放记录就可以直接修复,顺利存储可将日志区完成的iNode信息存入元数据区
但此类型多了一层读写操作,因此速率上会慢一些,尤其是写操作。频繁大量写入小文件时较为明显


文件系统管理
格式化分区:重新创建文件系统会损坏原有文件
在fdisk分区时删除键失效,可以按ctrl+删除键删除即可
fdisk分区后保存退出,使用partprobe /dev/sda来刷新分区才能继续格式化

mkfs:make file system
文件系统类型:
ext2、ext3、ext4、xfs、reiserfs、jfs、swap;网络层文件系统:nfs、ocfs2、gfs2
mkfs:
-t FSTYPE /dev/sda4

使用cat /proc/filesystems:可查看当前内核下支持的文件系统,需要更多文件系统可以添加新文件系统模块来添加

ext2格式化之后显示的信息:
filesystem label卷标:分区名
OS type:操作系统类型
Block size:块大小
Fragment size:偏移大小
xxxx inodes(共分了多少个iNode),xxxxx blocks(共分了多少块)
xxxx blocks reserved for the super user:有多少块预留给超级管理员使用
First data block=0 : 起始块
maximum filesystem blocks=xxxxxx 最大文件系统块
xx block groups:分了多少块组
xxxxx blocks per group,xxxxx fragments per group:每组有多少块,每组多少个偏移
xxxxx iNodes per group 每个组有多少个inod,基本是
superblock backups stored on blocks:都哪些块是备份块
xxxx,xxxxx,xxxxx,xxxxx,xxxxx
writing inode tables:done 写inode表完成
writing superblocks and filesystem accounting information:done 写超级块与文件系统信息完成

this filesystem will be automatically checked every 20 mounts or 180 days,whichever comes first。use tune2fs -c or -i to override。
建议此文件系统每挂载20次或者使用180天,进行一次检测。使用tune2fs -c 或 -i 来修复。

如果是ext3文件系统会多一行信息:
creating journal(4096 blocks):done 创建日志块完成

专门管理ext系列文件系统:
mke2fs:不加-j参数为ext2
-j:加此参数为ext3
-b BLOCK_SIZE:指定块大小,默认为4096;可用取值1024、2048或4096;
-L LABEL:指定分区卷标
-m #:指定预留给超级用户的块数百分比
-i #:用于指定多少字节的空间创建一个inode,默认为8192;这里给出的数值应该为块大小的2^n倍;
-N #:指定inode个数;
-F:强制创建文件系统;
-E:用于指定额外的文件系统属性;

查看块设备的文件信息
blkid:用于查询或查看block设备的属性或定位block设备属性
UUID
TYPE
LABEL:分区卷标

e2label:用于查看或定义卷标
e2label 设备文件 卷标:设定卷标

tune2fs:调整文件系统的相关属性
-j:不损坏原有数据,将ext2升级为ext3;但无法降级
-L LABEL:设定或修改卷标
-m #:调整预留百分比;
-r #:指定预留块数;
-o:设定默认挂载选项;
acl:访问控制功能
journal_data_ordered:日志类型
-C:
-c #:指定挂载次数达到#次后进行自检,0或-1表示关闭此功能
-i #:每挂载使用多少天后进行自检;0或-1表示关闭此功能
-l:显示超级块中的信息;

dumpe2fs:显示文件系统属性信息
-h:只显示超级块信息

fsck:检查并修复linux文件系统
-t FSTYPE:指定文件系统类型
-a:自动修复

e2fsck:专门检查或修复EXT2/EXT3文件系统
-f:强制检测
-a:自动修复
-p:默认选项,也是自动修复

挂载:将新的文件系统关联至当前根文件系统
mount:挂载
mount 设备 挂载点
设备:
设备文件:/dev/sda5
卷标:LABEL=“ ”
UUID:UUID=“ ”
挂载点:目录
要求:
1、此目录没有被其它进程使用
2、目录需事先存在
3、目录中原有文件将会被暂时隐藏;
mount单独使用:显示当前系统已经挂载的设备及挂载点
mount [options] [-o options] DEVICE MOUNT_POINT
-a:表示挂载/etc/fstab文件中定义的所有文件系统
-n:默认情况下;mount命令每挂载一个设备,都会把挂载的设备信息保存至/etc/mtab文件中;使用-n选项意味着挂载设备时,不把信息写入此文件;
-t FSTYPE:指定正在挂载设备上的文件系统的类型;不适用此选项时,mount会调用blkid命令获取对应文件系统的类型;
-r:只读挂载,挂载光盘时常用此选项
-w:读写挂载
-o:指定额外的挂载选项,也即指定文件系统启用的属性;
async:异步写入,硬盘比CPU速度要慢的多,异步是将cpu计算结果先输入至内存再写入磁盘,如果同步写入磁盘效率会被磁盘效率拖慢很多;
atime:最近一次访问时间,不更新为no atime,每次创建时间戳都会产生一次IO,影响性能
auto:设备能够使用-a选项
defaults:使用默认选项,没指定任何选项就使用默认
dev:如果当前文件系统中有设备文件,是否启用此设备,dev表示启用
exec:执行权限的可执行文件运行起来;
netdev:设备网络映射,网络断开等问题不重复挂碍
owner:允许普通用户挂载此文件系统
remount:重新挂载当前文件系统
ro:挂载为只读
rw:读写挂载
sync:同步写入
suid:

挂载完成后,要通过挂载点访问对应文件系统上的文件;

卸载:将某文件系统与当前根文件系统的关联关系予以移除;
umount:卸载某文件系统
umount 设备或挂载点
卸载注意事项:
挂载的设备没有被进程使用;

任务计划:
mail
cron
at
batch

swap分区:虚拟地址不感知底层物理内存使用情况,当物理内存用尽,就会将虚拟地址存入临时的存储空间中,等待物理内存空闲后再转入物理内存中。产生一种换进换出的过程,这个过程就叫做交换空间,可以使内存过载使用。overcommit
page out:将内存空间交换到磁盘的过程
page in:再从磁盘交换空间中取回到内存的过程


CPU:time slice 时间片
I/O设备:多路复用
内存:x86:(32位)
物理地址:物理内存中将所有内存分为了多个page frame页框,每4k作为一个存储单元
虚拟地址,线性地址:虚拟空间对应一个物理内存页框,交叉关联。这样将物理内存分配给不同的进程使用。

free:查看物理内存以及交换分区的使用情况
total:总空间
used:已使用空间
free:空闲空间
buffers:缓冲;均衡设备之间使用情况,主要是元数据
cache:缓存:缓存数据

swap空间不足如何添加:
首先新建新分区
fdisk /dev/sda
n(新建分区)默认值回车即可
L(选择82 linux swap进行分区类型选择)
p(查看分区)
w(保存分区并退出)
使用partprobe /dev/sda 刷新分区
创建交换分区:
mkswap /dev/sda8
-L LABEL:指定卷标
挂载交换分区:
swapon /dev/sda8
-a:启用所有的定义在/et/fstab文件中的交换设备
关闭交换分区:
swapoff /dev/sda8


dd命令:转换并复制一个文件
使用方式:
dd if=/etc/inittab of=/root/inittab
if=input file数据来源
of=output file数据存储目标
bs=1024:以1个字节为单位复制,block size 每次复制1024字节
count=2:一共复制多少个这样的字节,一共复制2个1024

备份mbr:
dd if=/dev/sda of=/mnt/usb/mbr.backup bs=512 count=1
恢复mbr:
dd if=/mnt/usb/mbr.backup of=/dev/sda bs=512 count=1
将光盘制作成iso文件:
cat /dev/cdrom > /root/rhel5.iso
dd if=/dev/cdrom of=/root/rhel5.iso

回环设备:
loopback,使用软件来模拟实现硬件


dd if=/dev/zero of=/var/swapfile bs=1M count=1024 创建一个1G的文件,硬盘会非常快的转速
/dev/zero:泡泡设备,是一个永远输出0的设备文件要多少给多少,与/dev/null黑洞给多少要走多少相反

创建一个镜像文件,1G空间模拟为一个硬盘可以当做120G甚至更多使用。磁盘无空间时应急使用,性能会比磁盘更差。
[root@localhost ~]# free 查看swap为4G空间
total used free shared buffers cached
Mem: 1004608 358960 645648 0 18976 148220
-/+ buffers/cache: 191764 812844
Swap: 4095992 0 4095992
[root@localhost ~]# dd if=/dev/zero of=/var/swapfile bs=1M count=1024 创建一个1G的设备文件
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 50.0761 s, 21.4 MB/s
[root@localhost ~]# ls -lh /var/swapfile 查看文件大小正好为1G
-rw-r--r--. 1 root root 1.0G Jun 28 04:47 /var/swapfile
[root@localhost ~]# mkswap /var/swapfile 创建swap空间
Setting up swapspace version 1, size = 1048572 KiB
no label, UUID=6e1c16b5-d3ee-4ed4-a33b-943c9b64028f
[root@localhost ~]# swapon /var/swapfile 启用此设备到swap空间
[root@localhost ~]# free -m 查看swap空间扩展到了5G
total used free shared buffers cached
Mem: 981 912 68 0 6 702
-/+ buffers/cache: 203 777
Swap: 5023 0 5023

dd和cp区别:
cp:以文件为单位复制,通过vfs进行复制,依托于文件系统之上
dd:复制的是底层的数据流,01代码为单位,最底层复制

dd命令:
bs=#
if=数据来源
of=数据存储目标
count=#
seek=#:开始出跳过多少。如:dd if=/dev/zero of=/var/swapfile2 seek=1023 bs=1M count=1
再查看文件[root@localhost ~]# ls -lh /var/swapfile2 仍然是1G,因为实际创建了1M但是跳过了1023M表面看是1G,其实是个假文件,使用du查看就是实际大小。
-rw-r--r--. 1 root root 1.0G Jun 28 05:05 /var/swapfile2

mount命令,可以挂载iso镜像
mount DEVICE MOUNT_POINT
-o loop:挂载本地回环设备
挂载iso镜像文件,直接挂载会提示不是设备文件。因此使用回环指令集进行挂载
mount -o loop /root/rhci-5.8-1.iso /media/
ls /media/ 就可以看到iso文件中的内容了

文件系统的配置文件/etc/fstab,所有写入此表的文件系统
OS在初始时,会自动挂载此文件中的文件系统

要挂载的设备 挂载点 文件系统类型 挂载选项 转储频率 文件系统检测次序
/dev/sda5 /mnt/test ext3 defaults,acl 0 0
第一个字段:要挂载的设备,可以使用LABEL卷标或UUID的方式指定也可以直接使用设备文件路径来指定
第二个字段:挂载点,挂载位置
第三个字段:文件系统类型
第四个字段:挂载选项,在默认选项后加acl即可启用ACL功能
第五个字段:转储频率(与文件系统备份相关,表示每多少天备份一次完全备份),定义多少天对此文件系统做一次备份。0表示不备份,1表示每天备份一次完全备份,2表示每隔1天做一次完全备份,
第六个字段:文件系统检测次序,每次开机的时候依次检测的次序,只有根为1,其他文件系统可同时为2,0表示不检查

mount -a:表示挂载fstab文件中定义的所有文件系统
挂载完成一个设备就会写入到先的mtab文件中
/etc/mtab文件中
-n:选项意味着挂载设备时,不把信息写入此文件;

如果一个设备卸载时提示此设备is busy,可以用以下命令查看使用者
fuser:验证每个进程正在使用的文件或套接字
-v:查看某文件上正在运行的进程 如:fuser -v /dev/test
-k:结束正在访问此文件的进程
-m:结束挂载点上的所有正在访问的进程 如:fuser -km /dev/test

压缩、解压缩命令
压缩格式:gz、bz2、xz、zip、Z、7z等等

压缩算法:算法不同,压缩比也会不同;
压缩比:压缩前减去压缩后的大小再比原来大小

compress:压缩,可以解压FILENAME.Z
uncompress:解压


xz、bz2、gz
以下命令只能压缩文件,并非目录,如果用在目录会把目录下的所有文件压缩
gzip:.gz
压缩:gzip /PATH/TO/SOMEFILE :压缩后会删除原文件
-d:也可以解压缩
-#:1-9:指压缩比,默认为6.最大为9
gunzip:解压缩
gunzip /PATH/TO/SOMEFILE.gz :解压缩后删除压缩文件
zcat /PATH/TO/SOMEFILE.gz 不解压的情况下,查看压缩文件内容

比gzip有着更大压缩比的压缩工具,使用格式近似
bzip2:.bz2
bzip2 /PATH/TO/SOMEFILE 也会删除原文件
-d:解压缩
-#:1-9压缩比,默认也是6
-k:压缩时可以保留原文件

bunzip2 /PATH/TO/SOMEFILE 解压压缩文件
bzcat:不解压直接查看压缩包内容进行

比bzip2压缩比还大的压缩工具,默认不安装,安装前请确定有/etc/yum.repos.d/server.repo文件,如没有网上下载放置此目录,放置之后,使用sed -i 's@instructor\.example\.com@172.16.0.1@g' server.repo
然后安装
yum install xz
安装后使用
xz:.xz
使用方式:
xz /PATH/TO/SOMEFILE :压缩,也会删除原文件
-d:解压缩
-#:1-9压缩比,默认也是6
-k:压缩时,保留原文件
unxz /PATH/TO/SOMEFILE :解压缩,也会删除原文件
xzdec /PATH/TO/SOMEFILE :也是解压缩工具
xzcat /PATH/TO/SOMEFILE :不解压直接查看压缩文件内容

zip:是很多操作系统默认就可以解压缩的文件,可压缩目录,但压缩比不大
zip test.zip test/*
zip FILENAME.zip FILE1 FILE2 ... 默认不删除原文件
unzip FILENAME.zip 解压命令
archive:归档压缩,归档本身并不意味着压缩,只有需要压缩的时候再压缩。
zip:既能归档又能压缩的工具。

tar:GNU版本的归档工具,只归档不压缩
使用方法:
tar option 压缩后的文件名 被压缩元文件
tar:归档
-c:创建归档文件
-f FILE.tar:操作的归档文件
-x:还原归档
--xattrs:表示归档的同时,保留其扩展属性信息,关键参数,备份时常用
-tf:不展开归档,直接查看归档了文件

归档后的文件可以再压缩,xz test.tar
这样执行两次才能展开文件或压缩和归档文件,可以使用
-zcf:先创建归档,再调用gzip压缩
-zxf:先调用gzip解压缩后展开归档,-z选项可省略

-jcf:先创建归档,再调用bzip2压缩
-jxf:先调用bzip2解压缩后展开归档,-z选项可省略

-Jcf:先创建归档,再调用xz压缩 红帽6之后版本支持
-Jxf:先调用xz解压缩后展开归档

cpio:归档工具,创建归档或展开归档,比tar更早期的工具

练习:写一个脚本
从键盘让用户输入几个文件,脚本能够将此几个文件归档压缩成一个文件
read 变量名:键盘赋值给变量
vi sum.sh

#!/bin/bash
#
echo "Input two intergers:"
read -t 5 -p "Input two intergers [100 and 1000]:" A B #使用-p选项可以省略上面的echo内容,给出提示的意思,-t #多少秒后超时。
[ -z $A ] && A=100
[ -z $B ] && B=1000
echo "$A plus $B is: $[$A+$B]"


vi myar.sh

#!/bin/bash
#
read -p "Three files:" FILE1 FILE2 FILE3
read -p "Destination:" DEST
read -p "Compress [gzip|bzip2|xz]:" COMP

case $COMP in
gzip)
tar -zcf $(DEST).tar.bz2 $FILE1 $FILE2 $FILE3 ;;
bzip2)
tar -jcf $(DEST).tar.bz2 $FILE1 $FILE2 $FILE3
;;
xz)
tar -cf $(DEST).tar.bz2 $FILE1 $FILE2 $FILE3
xz $(DEST).tar
;;
*)
echo "Unkown."
exit 9
;;
esac


脚本编程:
顺序结构
选择结构
if
case
循环结构
for
while
until

while循环:适用于循环次数位置的场景,要有退出条件,否则陷入死循环
语法:
while CONDITION; do
statement
...
done
计算100以内所有正整数的和
vim while.sh

#!/bin/bash
#
declare -i I=1
declare -i SUM=0

while [ $I -le 100 ]; do
let SUM+=$I
let I++
done

echo $SUM

用户输入的字符串全部替换为大写,除非是quit即可退出
vim translate.sh

#!/bin/bash
#
STRING=hello world #或适用 read -p "Input something:" SRTING

while [ $STRING != 'quit' ]; do
echo $STRING | tr 'a-z' 'A-Z'
read -p "Input something:" SRTING
done

hadoop登录脚本
#!/bin/bash
#
who | grep "hadoop" &>/dev/null
RETVAL=$?

while [ $RETVAL -ne 0 ]: do
echo " `date`, hadoop is not login."
sleep 5
who | grep "hadoop" &>/dev/null
RETVAL=$?
done

echo "Hadoop is logged in"

循环输入查看系统性能脚本

#!/bin/bash
#
cat << EOF
d|D) show disk usages.
m|M) show memory usages.
s|S) show swap usages.
*) quit.
EOF

echo -n -e "\033[31mYour choice:\033[0m"
read -p "You choice:" CHOICE
while [ $CHOICE != 'quit' ]: do
case $CHOICE in
d|D)
echo "Disk usage:"
df -Ph ;;
m|M)
echo "Memory usage:"
free -m |grep "Mem" ;;
s|S)
echo "Swap usage:"
free -m |grep "Swap" ;;
*)
echo "Unkonw." ;;
esac
echo -n -e "\033[31mAgain, your choice:\033[0m"
read -p "Again, your choice:" CHOICE
done

输出加色以及加粗:
echo -e "\033[1mHello\033[0m,world." # \033开始表示字体1m表示字体加粗到最后的\033结束
echo -e "\033[31mHello\033[0m,world." #31m表示Hello红色字体,32m表示绿色,33m表示黄色,34蓝色,35紫色,36浅蓝,37灰色。
echo -e "\033[41mHello\033[0m,world." # 41m表示Hello背景为红色
echo -e "\033[37;41mHello\033[0m,world." # 37;41m表示背景色为红色字体为灰色
echo -e "\033[1;37;41mHello\033[0m,world." # 1;37;41m表示背景色为红色字体为灰色并加粗显示 5;37;41m是字体闪烁,7是把字符颜色和背景颜色反转

64位操作系统对应库为:/lib64
32位操作系统对应库为:/lib

协议:双方都要遵循某种规则的控制方式
MB和Mb区别,Mb除以8才能得到MB
IDE:133Mbps 并行口
SATA1:300Mbps SATA2:600Mbps SATA3:6Gbps 串行口
USB2.0 : 40Mbps USB3.0 : 480Mbps 串行口
SCSI:small computer system interface,小型计算系统接口,内部有芯片控制器,大大提高性能,10000转、15000转
UItraSCSI,320Mbps,并行总线
SAS:2.5英寸,转速快

RAID控制器:独立冗余磁盘阵列,将多块硬盘组合提供存储功能

条带化
RAID级别:仅代表磁盘组织方式不同,没有上下之分;

RAID 0:条带,速度快,性能提升,读写。但无冗余能力。存储利用率:nS 2块及以上
RAID 1:镜像,写性能下降,读性能提升。冗余能力较强,空间利用率:50% 2块及以上
RAID 0+1:条带+镜像,任何一块盘坏掉整个磁盘体系都会受到影响。性能读写提升,有冗余能力,空间利用率50%。4块及以上
RAID 1+0:镜像+条带,性能与0+1差别不大,但磁盘损坏修复时会显示出优势,只影响单个磁盘速率,其余不影响。读写性能提升,冗余能力有,空间利用率:50% 4块及以上
RAID 5:校验码,校验码盘很容易成为性能瓶颈,因此磁盘轮流做校验码盘,只允许坏1块磁盘。读写都提升,冗余能力有,空间利用率N-1/n。至少3块盘
RAID 6:校验码,校验两次,增加可靠性,但需要增加校验码盘
RAID 5+0:两个RAID5,再进行条带华。性能读写提升,冗余能力有,空间利用率(n-2)/n 至少需要6块盘

jbod:主要目的实现将多个小盘组合成一个块大盘来用。只是容量扩展使用。Hadoop就需要此技术。性能无提升,冗余能力无,空间利用率100%,2块及以上磁盘

硬RAID
BIOS界面中配置

软RAID
linux:md:multi disks,模拟一个逻辑RIAD,创建好的逻辑RIAD会在/dev/md0设备,使用CPU进行数据分片,性能较差,依赖于操作系统,如果操作系统坏掉RIAD也将损坏。分区必须标识为fd类型linux软raid,使内核可以直接识别设备。

软RIAD命令
md:功能模块

mdadm:将任何块设备做成RAID,分区也可以为RAID,但无意义,实验使用。
模块化的命令:
创建模式 例如:mdadm -C /dev/dm0 -a yes -l 0 -n 2 /dev/sda{5,6} -l级别改为1就是raid1
-C
专用选项:
-l:指定级别
-n #:设备个数
-a {yes|no}:自动为其创建设备文件
-c:chunk(数据块)大小,2^n,默认为64K
-x #:指定空闲盘个数,与-n设备个数对称
管理模式 例:mdadm /dev/md1 --fail /dev/sda7 模拟/dev/sda7在md1例损坏
-a,--add,--del,-r,--remove,-f,--fail,--set-faulty
监控模式
-F
增长模式
-G
装配模式
-A

扫描当前软riad信息:
mdadm -d --scan
写入到配置文件中,实现自动装配,无需指定设备
mdadm -d --scan > /etc/mdadm.conf

停止阵列:
mdadm -S /dev/md#
--stop

显示raid设备详细信息
mdadm -D /dev/md1

使用此命令查询软RAID
cat /proc/mdstat

可以将cat /proc/mdstat命令每隔2秒显示一次
watch:周期性的执行指定命令,并以全屏方式显示结果
使用格式:
watch -n # 'COMMAND'
-n #:指定周期长度,单位为秒,默认为2
watch 'cat /proc/mdstat'

改变块大小来提升软raid性能:
mke2fs -j -E stride=16 -b 4096 /dev/md0
-E stride:指定条带大小,条带等于chunk比上brk大倍数

列出模块:lsmod
mdadm:用户空间工具,管理工具

MD:Meta Device /dev/dm#
DM:Device Mapper 提供逻辑设备 RAID,LVM2
实现动态增减
DM是LVM2的核心
快照
多路径

raid只是防止硬件损坏的数据保护机制,并无法保护误删除之类的人为操作性数据丢失情况。

zfs文件系统就可以实现快照功能和卷功能

PV:Physical Volume 物理卷
创建:pvcreate
pvcreate /dev/sda{10,11} 实际情况创建为设备pvcreate /dev/sda
删除:pvremove
扫描:pvscan
查看:pvdisplay
移动:pvmove ,主要用于将要移除的某个PV设备中的PE数据块移至其他PV
pvmove /dev/sda11 将sda11分区上的pe数据挪走
PE:Physical Extend 物理盘区,类似raid中的chunk条带,划分为多个区块
VG:Volume Group 卷组
创建:vgcreate myvg为卷组名可自定义
vfcreate myvg /dev/sda{10,11}
-s #:可指定pe盘区大小,默认pe盘区大小为4MB 例:vfcreate -s 8M myvg /dev/sda{10,11}
删除:vgremove
vgremove myvg
增加:vgextend
vgextend myvg /dev/sda12
缩减:vgreduce 缩减前一定要将此pv中的pe使用pvmove挪走
vgreduce myvg /dev/sda11 将sda11从myvg卷组中移除
查看:vgdisplay,vgs
扫描:vgscan

LG:Logical Volume 逻辑卷
创建:lvcreate
lvcreate -n LV_NAME -L #G VG_NAME 例:lvcreate -n testlv -L 50M myvg
删除:lvremove
lvremove /dev/mapper/myvg-testlv
增加:lvextend
缩减:lvreduce
改变大小:lvresize
查看:lvdisplay,lvs
扫描:lvscan

fdisk命令最多只能支持到15个分区

创建分区的过程:
物理边界
物理边界内部系统边界
逻辑边界

一、扩展逻辑卷:
先扩展物理边界,再扩展逻辑边界
扩展物理边界:
lvextend
-L [+]#G /PATH/TO/LV:#指扩展容量
扩展逻辑边界:
resize2fs
resize2fs /PATH/TO/LV #G:#指原有容量+扩展容量的总量
-p:加-p参数后无需指定#G,指有多大的物理边界加多大容量


二、缩减逻辑卷:
先缩减逻辑边界,再缩减物理边界
缩减容量风险很大,一定不要在线缩减
注意:
1、不能在线缩减,先卸载 df -lh查看分区情况,umount卸载
2、缩减后的容量可以容纳原有数据
3、在缩减前,应先强行检查文件系统,确保文件系统处于一致性状态;
检测文件系统命令:e2fsck -f /dev/myvg/testlv
缩减逻辑边界:
resize2fs
resize2fs /PATH/TO/PV #G :#G指缩减后的容量
缩减物理边界:
lvreduce
-L [-]#G /PATH/TO/LV:#指缩减容量

重新挂载:mount分区

三、快照卷:
快照卷主要作用是备份:
1、生命周期为整个数据时长,在这段时长内数据增长量不能超出快照卷大小,超出就会损毁;
2、快照卷应该是只读的
3、快照卷跟原卷在同一卷组内

创建快照卷:
lvcreate
-s:表示快照卷
-p r|w:指定权限
格式:lvcreate -L #G -n SLV_NAME -s -p r /PATH/TO/LV
例:lvcreate -L 50M -n testlv-snap -s -p r /dev/myvg/testlv
移除快照卷顺序:
umount卸载掉使用的快照卷
移除快照卷:
lvremove /dev/myvg/testlv-snap

快照卷至保留创建快照卷那一刻的数据,之后改变数据快照卷中不会保存。

脚本编程控制结构:
顺序
选择
if
case
循环
for
while
until


while CONDITION; do
statment
done

例:
#!/bin/bash
#
read -p "Input someting:" STRING

while [ $STRING != 'quit' ]; do
echo $STRING |tr 'a-z' 'A-Z'
read -p "Again,Input someting:" STRING
done
进入循环:条件满足
退出循环:条件不满足

until循环:
until CONDITION; do
statment
...
done

进入循环:条件不满足
退出循环:条件满足
例:
#!/bin/bash
#
read -p "Input someting:" STRING

until [ $STRING == 'quit' ]; do
echo $STRING |tr 'a-z' 'A-Z'
read -p "Input someting:" STRING
done

while与until相反

until循环样例:hadoop登录后脚本停止
#!/bin/bash
#
who |grep "hadoop" &> /dev/null
RETVAL=$?

until [ $RETVAL -eq 0 ]; do
echo "hadoop is not logged in."
sleep 5
who | grep "hadoop" &> /dev/null
RETVAL=$?
done
echo "hadoop is logged in."

简易写法:
#!/bin/bash
#
until who |grep "hadoop" &> /dev/null; do
echo "hadoop is not logged in."
sleep 5
done
echo "hadoop is logged in."

for 变量 in 列表;do
循环体
done

另一种用法:
for (( expr1 ; exprl2 ; expr3 )); do
循环体
done

expr1:指定初始条件
expr2:什么时候退出循环
expr3:修正这个变量的值

100以内正整数的和
之前写法:
#!/bin/bash
#
declare -i SUM=0
for I in {1..100}; do
let SUM+=$I
done
echo $SUM

新写法:
#!/bin/bash
#
declare -i SUM=0
for ((I=1;I<=100;I++)); do
let SUM+=$I
done
echo $SUM

100以内所有偶数的和
#!/bin/bash
#
declare -i SUM=0
for ((I=2;I<=100;I+=2)); do
let SUM+=$I
done
echo $SUM

ping一个IP段,查看地址段内的IP是否存活
ping
-c #:指定ping的次数,ping #次结束
-W #:指定ping的超时秒数,ping #秒结束

awk
取值用法:
awk 'PATTERN {ACTION}' file
print $1
例:df -Ph |awk '{print $1,$3}'
$1:表示第一列;
$0:表示一整行的所有字段
NF:表示字段个数
$NF:最后一个字段

awk -F: '{print $1,$3}' /etc/passwd
-F:指定分隔符,默认情况下为空白

脚本完成磁盘分区格式化
取出现有磁盘:
fdisk -l 2> /dev/null |grep "^Disk /dev/[sh]d[a-z]" |awk -F: '{print $1}'
删除一块磁盘的所有数据:将分区表覆盖掉即可
dd if=/dev/zero of=/dev/sdb bs=512 count=1
sync 把内存中的所有内容同步至磁盘

vim setpart.sh

#!/bin/bash
#
echo 'n
p
1

+20M
n
p
2

+512M
n
p
3

+128M
t
3
82
w' | fdisk /dev/hda

以上


写个脚本
1、列出当前系统所有磁盘,让用户选择,如果quit则退出,如果选择错误提示重新选择
2、当前用户选择后,提醒用户确认接下来的操作可能会损坏数据,并请用户确认,如果用户选择y就继续,否则让用户重新选择
3、抹除那块硬盘上的所有分区(提示:抹除所有分区后执行sync命令,并让脚本睡眠3秒钟后再分区);并未其创建三个分区,第一个20M,第二个512M,第三个128M,且第三个为swap分区类型;(提示:将分区命令通过echo传送给fdisk即可实现)

vim partdisk.sh

#!/bin/bash
#
echo "Initial a disk ..."
echo -e "\033[31mWarning: \033[0m "
fdisk -l 2> /dev/null |grep -o "`Disk /dev/[sh]d[a-z]"

read -p "Your choice: " PARTDISK

if [ $PARTDISK == 'quit' ]; then
echo "quit"
exit 7
fi

until fdisk -l 2> /dev/null |grep -o "`Disk /dev/[sh]d[a-z]" | grep "^Disk $PARTDISK$" &>/dev/null; do
read -p "Wrong option,Your choice agein: " PARTDISK
done

read -p "Will destroy all data,continue" CHOICE
until [ $CHOICE == 'y' -o $CHOICE == 'n' ]; do
read -p "Wrong option,Your choice agein: " CHOICE
done

if [ $CHOICE == 'n' ]; then
echo "Quit"
exit 9
else
dd if=/dev/zero of=$PARTDISK bs=512 count=1 &> /dev/null
sync
sleep 3
echo "Partition"
echo 'n
p
1

+20M
n
p
2

+512M
n
p
3

+128M
t
3
82
w' | fdisk $PARTDISK &> /dev/null
partprobe $PARTDISK
sync
sleep 2
mke2fs -j ${PARTDISK}1 &> /dev/null
mke2fs -j ${PARTDISK}2 &> /dev/null
mkswap ${PARTDISK}3 &> /dev/null
fi

找到对应mount点自动卸载
vim umount.sh

#!/bin/bash
#
for I in `mount |grep "/dev/sdb" | awk '{print $1}'`; do
fuser -km $I
umount $I
echo :$I unmount ok."
done

网络通过协议protocol进行传输和信号转换
10Mbps的含义是每秒钟传输的bit个数,每秒传输10M个bit
如果换算成我们熟知的MB=MByte就需要把10Mbps/8 除以8之后得出大B字节

线路仲裁:解决某个时刻哪个主机可以使用某个传输介质,避免网络冲突
以太网的核心标志:
CSMA/CD:Carrier Sense Multi Access Collision Detection 载波侦听多路访问,冲突检测
发送信号前,先探测线路是否忙碌,如果空闲立即发送信号,如忙碌则回退等待一段时间后再发起探测

IBM商业化专利产品,所以未流行起来:
令牌环网络:此网络中游走着一个令牌环token,谁需要发送信号就抓住这个令牌环就可以发送信号。只有持有令牌环的主机才可以发送信号

星型网络结构:
也可以理解成为总线型网络,典型的HUB集线器组成的网络

MAC:media Access Control 介质访问控制,每台主机网络中的标识符
MAC地址往往被封装在TCP报文的首部,报头

ARP:将逻辑地址(IP地址)转换成MAC地址的过程
RARP:反向解析,将MAC地址解析为逻辑地址(IP地址)

网桥:连接两个网络的设备,有效隔离两个网络的冲突

网关:两个网络之间通信的接口,在两个网络之间转发报文。

子网掩码:标记网络位和标记网络地址,换算1与任何数相遇都得任何数,0与任何数相遇都得0

广播:一对多
单播:一对一

半双工:同一时刻只能向一方发送信号,同轴线
全双工:同一时刻两个主机可以相互发送信号,双绞线:绿橙白棕,

电子是由负极流向正极;电子流动过程当中,会有电阻将信号衰减,因此远距离的传输信号会差。
中继器:通过中继器来将减弱的信号重新加压增强。

交换机:最核心的功能为内置学习的主机与对应端口的表,利用此表进行转发传输。

路由表:标记每个网络域对应的接口位置的表,实现不同网络间的通信
路由器学习路由:通过RIP2\OSPF等协议学习不同路由过程

端口号:同一个主机上的不同进程的标记,可以通过端口号做主机进程之间通信。端口号范围:0-65536
被动打开:有人访问端口再开放
主动打开:有没有人端口都保持开放状态
套接字(socket):IP与端口的绑定,IP:port

OSI(开放互联参考模型) 7层网络协议:
物理层:封装报文的前导码,报文的分隔符
数据链路层:封装MAC,记录源MAC和目标MAC
网络层:封装IP,记录源IP和目标IP
传输层:封装端口,记录源端口和目标端口
会话层:双方建立会话过程
表示层:加密解密,是否压缩
应用层:具体应用协议,HTTP\HTTPS\FTP等等

TCP/IP协议:
物理层:封装MAC,记录源MAC和目标MAC
网络层:封装IP,记录源IP和目标IP
传输层:封装端口,记录源端口和目标端口
应用层:具体应用协议,HTTP\HTTPS\FTP等等

IP地址分类:
A类地址:第一段为网络地址,后面三段全为主机地址;范围:2的24次方-2个主机 255.0.0.0 8位掩码 首位:0-127 127个A类地址,127位回环地址不可用,有效地址为1-126。2的7次方-1个A类网络
B类地址:前两段为网络地址,后两段为主机地址;范围:2的16次方-2个主机 255.255.0.0 16位掩码 首位:128-191 64个B类地址,2的14次方个B类网络
C类地址:前三段为网络地址,最后一段为主机地址;范围:2的8次方-2个主机 255.255.255.0 24位掩码 首位:192-223 32个C类地址,2的7次方个主机地址,反之2的21次方的C类网络
D类地址:范围:224-239
E类地址:范围:剩余

私有地址:
A类:10.0.0.0/8
B类:172.16.0.0/16-172.31.0.0/16
C类:192.168.0.0/24-192.168.255.0/24

网络路由:目的地址是网络的
主机路由:目标地址是主机的

0.0.0.0表示任意主机,默认路由或缺省路由

划分子网:
从主机位取出部分来作为网络位使用;
IP地址每一段共8位借出2位8-2=6位

每一位可以容纳多少主机?2的6次方减2=62个

网络变化:
00
01
10
11
不考虑全0和全1
01 00 0001 - 01 11 1110:
网络地址:201.1.2.64 广播地址:201.1.2.127 子网掩码:26位
65 - 126
10 00 0001 - 10 11 1110
网络地址:201.1.2.128 广播地址:201.1.2.191 子网掩码:26位
129 - 190

反之还可以合并为一个大网

TCP:Transmission Control Protocol传输控制协议
经过三次握手建立会话,每次都会有对端确认才会传输报文。
典型协议:HTTP、HTTPS、FTP、POP3、SMTP
UDP:User Datagram Protocol用户数据报协议
报文传输只是将报文放置网络中,不管是否传输到目的,如果没发送成功会将报文原路返回。
典型协议:DNS、DHCP、TFTP
报文内容:
源端口号(16位);目的端口号(16位);
序列号(32位);
确认号(32位);
首部长度(4位);保留位(3位);紧急位URG,确认位ACK,推送位PSH(需要立即传输的位,不缓存),重置位RST(网络抖动,断开,重新建立连接的过程),同步位SYN,断开FIN;窗口大小(16位)接收方缓冲区预留的个数和链路中可存储的个数;
TCP校验和(16位);紧急指针(16位);
可选段位;
数据包;

TCP传输过程:
源端首选发送请求发起:
SYN=1(请求),sn=100(请求序列号)
对端返回请求确认:
SYN=1(请求应答),ACK=1(确认请求),an=101(回应请求序列号收到并回应可以继续发送),sn=300(给源端返回的报文序列号)
源端再次确认对端请求:
ACK=1(确认请求),sn=101(第101个请求报文),an=301(确认对端的第300个报文)
开始传输数据,已建立连接通信过程:
发送,确认收到返回,再次发送的过程

发送断开连接请求;
FIN=1
然后对端确认断开请求;
ACK=1
然后对端再发起断开请求;
FIN=1
源端确认断开请求;最终断开连接;
ACK=1

3次握手,4次断开

User Space:所有用户进程都在用户空间运行
Kernel Space:所有内核功能全部在内核空间运行,网络功能,文件系统等功能

bonding网卡来完成网卡冗余

主机接入网络步骤:
IP
NETMASK
GATEWAY
HOSTNAME
linux下可配置3个DNS地址
DNS1
DNS2
DNS3
手动指定
DHCP:Dynamic Host Configuration Protocol
路由

linux网络功能属于内核功能:
lo接口:本地回环
eth[0-9]:以太网网卡
ppp[0-9]:点对点连接

RHEL5:
在/etc/modprobe.conf中有队硬件设备的别名设置,定义了eth0和eth1对应的设备驱动
RHEL6:
在/etc/udev/rules.d/目录下有个70-persistent-net.rules文件,明确定义了网卡的MAC地址对应的eth0和eth1的名称

ifconfig:关于网卡是任何属性,RX代表接受到的报文个数,TX代表发送的数据报个数,txqueuelen传输队列的长度,接收到的字节数和发送的字节数等等,

ifconfig eth[0-x]
-a:显示所有接口的配置信息
-n:以数字方式显示各主机或端口等相关信息
ifcofnig ethx IP/MASK [up|down]
配置立即生效,但重启网络服务或主机,都会失效

网络服务:
RHEL5:/etc/init.d/network [start|stop|restart|status]
RHEL6:/etc/init.d/NetworkManager [start|stop|restart|status]
在THEL6中可禁用上面的方式回归RHEL5的使用方式
禁用方法;


网关:
route:Flags显示U为开启的路由,UG是网关路由,无需路由通过网关可直接到达的。
格式:
route add -net|-host DEST gw NEXTHOP
route add default gw NETXTHOP
add:添加路由
-host:主机路由
-net:网络路由
-net 0.0.0.0 如:route -net 10.0.0.0.0/8 gw 192.168.10.1
del:删除路由
-host
-net
例:route del -net 10.0.0.0/8 [gw NEXTHOP]
route del -net 0.0.0.0
route del default

配置立即生效,但重启网络服务或主机,都会失效

网络配置文件:
/etc/sysconfig/network

网络接口配置文件:
/etc/sysconfig/network-script/ifcfg-INTERFACE_NAME
DEVICE=:关联的设备名称;要与文件名的后半部保持一致“INTERFACE_NAME”
BOOTPROTO={static|none|dhcp|bootp}:引导协议;要使用静态地址,使用static或none;dhcp表示使用DHCP获取地址;
IPADDR=:IP地址
NETMASK=:子网掩码
GATEWAY=:设定默认网关
ONBOOT=:开机时是否自动激活此网络设备
HWADDR=:硬件地址,要与硬件中的地址保持一致,可省;
USERCTL={yes|no}:是否允许普通用户控制此接口;
PEERDNS={yes|no}:是否在BOOTPROTO为dhcp时接受由DHCP服务器指定的DNS地址;

不会立即生效,但重启网络服务或主机都会生效,永久生效的配置方式。

永久生效路由配置方式:
/etc/sysconfig/network-script/route-ethx
添加格式1:
DEST via NETXTHOP
例:
在route-ethx文件中添加 192.168.10.0/24 via 10.10.10.254

添加格式2:
ADDRESS0=
NETMASK0=
GATEWAY0=
例:
ADDRESS0=192.168.10.0
NETMASK0=255.255.255.0
GATEWAY0=10.10.10.254

DNS服务器指定方法只有一种:
vim /etc/resolv.conf
nameserver DNS_IP_1
nameserver DNS_IP_2
nameserver DNS_IP_3

指定本地解析:
vim /etc/hosts
添加内容:
172.16.0.1 www.magedu.com www
主机IP 主机名 主机别名
正常解析顺序:
DNS缓存-->hosts-->DNS服务器

配置主机名:
hostname HOSTNAME 立即生效,但不是永久有效
/etc/sysconfig/network 重启也可生效
HOSTNAME=:写入主机名
更改文件之后不会立即生效,甚至重启网络服务都不会生效,需要手动执行hostname hello.magedu.com来生效
NETWORKING=[yes|no] 本机是否启用网络功能的总开关,设置为no如果配置IP都不能生效
NETWORKING_IPV6=[yes|no]:是否启用IPV6
GATEWAY=:全局的默认网关;如果网卡也设置了网关,那么谁的范围小谁来生效

RHEL5:
setup:system-config-network-tui
system-config-network-gui :必须图形化界面使用

ifconfig,老旧命令

iproute2包提供了ip命令
ip
link:网络接口属性
addr:协议地址,ip地址
route:路由

link:
show:查看IP地址信息
ip -s link show:查看每个网卡流量的详细信息
set DEVICE {up|down|arp {on|off}}: 例如:ip link set eth1 down 关闭eth1网卡
promisc {on|off}:混杂模式,抓包时会用到
mtu MTU值:设置MTU值
dynamic {on|off}:
multicast {on|off}:启用关闭多个功能
txqueuelen PACKETS:指定传输队列的长度
name NEWNAME:更改网卡名称
addr:
add:添加地址
ip addr add ADDRESS dev DEV_NAME
例:ip addr add 10.2.2.2/8 dev eth1 也可以添加secondary非主要地址,用ip addr show 查看,ifconfig是查看不到的
也可以使用ip addr add 10.2.2.2/8 dev eth1 label eth1:1 来添加别名,这样用ifconfig就可以查到了
del:删除地址
ip addr del ADDRESS dev DEV_NAME
例:ip addr del 10.2.2.2/8 dev eth1
show:查看地址
to:模糊查找
ip addr show eth1 to 192.168.100/24 可以使用to匹配完整的地址信息
label:只显示别名地址
flush:清除地址,一次性删除多个地址
ip addr flush eth1 to 10/8 将10开头的8位子网掩码的地址全部删除
route:
blackhole:黑洞,把网络引向一个黑洞
unreachable:主机不可达,主机存在但不让外界感知时可用
prohibit:禁ping
add:添加路由
例:ip route add to 10.0.0.0/8 dev eth0 via 172.16.0.1 添加一条路由10.0.0.0网络通过eth0设备通往下一跳地址172.16.0.1
change:修改路由
replace:替换路由
to PREFIX(default):到某个地址
via ADDRESS:通过网关
dev DEVNAME:指定设备
show:查看路由信息
to SELECTOR:显示某个路由,支持模糊查找
flush:清除路由表
to PREFIX:清除某些路由,支持模糊查找清除

tc命令可实现流量控制

linux下一块网卡可以使用多个地址;
网络设备可以别名:
eth0
ethX:X,eth0:0,eth0:1,....
方法:
ifconfig eth0:0 172.16.200.33/16 临时生效
永久生效方法:
新建文件ifcfg-ethX:X
/etc/sysconfig/network-scripts/ifcfg-ethX:X
DEVICE=ethX:X
...
非主要地址不能使用DHCP动态获取;

软件包管理:

应用程序:
程序,Architecture
程序:指令+数据
C语言:源代码-->(编译)二进制格式
脚本:解释器(二进制程序)

源代码-->编译(转换为二进制格式)-->链接()-->运行
程序:
库:
静态
动态
静态链接
动态链接
共享库


配置文件:
一般由变量组成

lnux下所有目录
/boot
/etc
/usr
/var
/dev
/lib
/tmp
/bin
/sbin
/proc
/sys
/mnt
/media
/home
/root
/misc
/opt
/srv

系统启动就需要用到的程序,这些目录不能挂载额外的分区,必须在根文件系统的分区上:
二进制程序 /bin,/sbin
库 /lib
配置文件 /etc
帮助文件 /user/share/man


操作系统的核心功能,可以单独分区:
/usr/
bin
sbin
lib

第三方软件,完全独立的运行环境,可以单独分区:
/usr/local
bin
sbin
lib
etc
man

早期的第三方软件安装位置
/opt

内核自我管理的分区,默认为空,不能单独分区:
/proc
/sys

设备目录,不能单独分区:
/dev
udev:动态创建设备文件,2.6内核提供的新功能

用户目录存放位置
/home

管理员家目录,不可单独分区
/root

日志文件存放目录,建议单独分区
/var

内核,initrd(initramfs)
/boot
内核:
系统启动过程:bootloader无法识别LVM,因此boot分区需要作为基本分区使用,创建500M即可
POST自检-->BIOS(HD)-->(MBR)bootloader(文件系统结构,ext2、ext3,xfs)-->内核

程序:指令+数据
指令:芯片
CPU:普通指令,特权指令
指令集

C语言:
PowerPC:二进制格式
x86:
x86:汇编
powerpc:汇编

软件包管理器:
打包成一个文件:二进制程序,库文件,配置文件,帮助文件
生成数据库,追踪所安装的每一个文件

软件包管理器的核心功能:
1、制作软件包;
2、安装、卸载、升级、查询、校验;

三大主流软件包发型厂商:RedHat,SUSE,Debian
RedHat,SUSE:RPM
RedHat Package Manager
RPM is Package Manager
Debian:dpt

依赖关系:
x-->y-->z 循环依赖关系

前段工具:update,apt-get,yum:Yellowdog Update Modifier

后端工具:RPM,dpt

rpm命令:
rpm:
数据库:/var/lib/rpm目录下
rpmbuild:

安装、查询、卸载、升级、校验、数据库的重建等工作;

rpm命名:
包:组成部分
主包:
bind-9.7.1-1.i586.el5.rpm
子包:
bind-libs-9.7.1-1.i586.el5.rpm
bind-utils-9.7.1-1.i586.el5.rpm
包名格式:
name-version-release.arch.rpm
bind-major.minor.release-release.arch.rpm

主版本号:重大改进
次版本号:某个子功能发生重大变化
发行号:修正了部分bug,跳转了一点功能

源代码包:bind-9.7.1.tar.gz

rpm包格式:
二进制格式:安装简单,默认情况下均为二进制格式
二进制格式的rpm包是由作者下载源程序,编译配置完成后,制作成rpm包的
noarch表示无需平台支持,任何平台都可以安装
源码格式:需要编译,更有益发挥硬件性能

rpm:
1、安装:
rpm -ivh /PATH/TO/PACKAGE_FILE
-v:显示安装详细过程
-vv:显示更详细的过程
-h:以#显示进度 ;每个#号显示2%的进度
--nodeps:忽略依赖关系;但可能导致软件安装后无法正常使用
--replacepkgs:重新安装,替换原有安装
--replacepkgsfile:替换文件
--oldpackage:降级,降回原来版本
--force:强制安装,可以实现重装或降级

2、查询:
rpm -qa PACKAGE_NAME 例:rpm -qa z*
-q:查询
--scripts:查询指定包中包含的脚本
-qa:查询所有rpm包
-qi:查询指定包的说明信息
-ql:查询指定包安装后生成的文件列表
-qf /PATH/TO/SOMEFILE:查询指定的文件是由哪个rpm包安装生成的;
-qc:查询指定包安装的配置文件
-qd:查询指定包安装的帮助文件
如果某个rpm包尚未安装,我们需要查询其说明信息、安装以后会生成的文件;
rpm -qpi /path/to/package_file
rpm -qpl /path/to/package_file

3、升级
rpm -Uvh /PATH/TO/NET_PACKAGE_FILE:如果装有老版本的,则升级;否则,安装
rpm -Fvh /PATH/TO/NET_PACKAGE_FILE:如果装有老版本的,则升级;否则,退出
--oldpackage:降级,后跟降级的包

4、卸载
rpm -e PACKAGE_NAME
--nodeps:忽略依赖关系;

5、校验
rpm -V PACKAGE_NAME 可以查看包相关的文件或文件内容是否有缺失

6、重建数据库
rpm数据库位置:/var/lib/rpm
rpm
--rebuilddb:重建数据库,一定会重新建立;
--initdb:初始化数据库,没有才建立,有就不用建立;

7、检验来源合法性,及软件包完整性:
加密类型:
对称:加密解密使用同一个秘钥
公钥:一对儿秘钥,公钥,私钥;公钥隐含于私钥中,可以提取出来,并公开出去;
单向:
redhat中在/etc/pki/rpm-gpg目录下有一个文件RPM-GPG-KEY-redhat-release
rpm -K PACKAGE_NAME
dsa,gpg:验证来源合法性,也即验证签名;
sha1,md5:验证软件包完整性;可以使用--nodigest,略过此项
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release:导入秘钥文件
rpm -K --nodigest PACKAGE_NAME 只验证签名不验证完整性

rpm --> yum

yum repository yum仓库
文件服务
ftp
web
local file
yum client
配置文件
yum仓库
RedHat
DVD
rpm包
元数据文件
createrepo
每个RedHat系统光盘中的server目录下为系统自带的所有rpm包以及repodata元数据目录

HTML:Hypertext Mark Language 超文本标记语言
XML:eXtened Mark Language 可扩展标记语言

XML,JSON:半结构化的数据
yum仓库中的元数据文件:
primary.xml.gz
所有RPM包的列表;
依赖关系;
每个RPM包安装生成的文件列表;
fileliests.xml.gz
当前仓库中所有RMP包的所有文件列表;
other.xml.gz
额外信息,比如RPM包的修改日志;
repomd.xml
记录的是上面三个文件的时间戳以及校验和
comps*-.xml
RPM包分组信息

RedHat6的repodata元数据目录在光盘根目录下

yum目录挂载点RedHat5:ftp://172.16.0.1/pub/{Server,VT,Cluster,ClusterStorage}

配置文件:/etc/yum.conf
cachedir:yum缓存的目录,yum在此存储下载的rpm包和数据库,一般是/var/cache/yum。
debuglevel:除错级别,0──10,默认是2
logfile:yum的日志文件,默认是/var/log/yum.log。 pkgpolicy:包的策略。一共有两个选项,newest和last,这个作用是如果你设置了多个repository,而同一软件在不同的repository中同时存在,yum应该安装哪一个,如果是newest,则yum会安装最新的那个版本。如果是last,则yum会将服务器id以字母表排序,并选择最后的那个服务器上的软件安装。一般都是选newest。 distroverpkg:指定一个软件包,yum会根据这个包判断你的发行版本,默认是redhat-release,也可以是安装的任何针对自己发行版的rpm包。 exactarch,有两个选项1和0,代表是否只升级和你安装软件包cpu体系一致的包,如果设为1,则如你安装了一个i386的rpm,则yum不会用1686的包来升级。
retries,网络连接发生错误后的重试次数,如果设为0,则会无限重试。 tolerent,也有1和0两个选项,表示yum是否容忍命令行发生与软件包有关的错误,比如你要安装1,2,3三个包,而其中3此前已经安装了,如果你设为1,则yum不会出现错误信息。默认是0。
除了上述之外,还有一些可以添加的选项,如exclude=,排除某些软件在升级名单之外,可以用通配符,列表中各个项目要用空格隔开,这个对于安装了诸如美化包,中文补丁的朋友特别有用。
gpgchkeck= 有1和0两个选择,分别代表是否是否进行gpg校验,如果没有这一项,默认好像也是检查的。

yum仓库配置文件:/etc/yum.repos.d/目录下,只保留.repo结尾的文件即可
rhel-debuginfo.repo文件
如何为yum定义repo文件:
[Repo_ID] 仓库ID,唯一标识符
name=Description
baseurl=访问路径,有一下三种格式
ftp://
http://
file:///
enabled={1|0} 1为启用0位禁用
gpgcheck={1|0} 是否检查软件包来源的合法以及完整性,默认是1开启的,开启时需要指定gpgkey
gpgkey=指定路径

yum命令:
install:安装包
-y:自动回答为yes
--nopgpcheck:无需检查来源包
update:升级包
update-to:升级到所指定的版本
check-update:检测有多少可用更新
remove|rease:卸载包
provides|whatprovides:查看指定的文件或特性是由哪个包安装生成的
list:列出yum仓库当中的所有包
支持glob
all:默认
available:仓库中有但未安装的,可用的
installed:已经安装的
updates:可用的升级包
repolist [all|enabled|disabled]:显示repo列表及其简要信息
all:
enabled:默认
disabled
clean:清除缓存
packages:清理RPM包
headers:详细信息
metadata:元数据文件
dbcache:库缓存
all:所有,常用
groupinstall:安装组
localinstall:本地安装
downgrade:降级
reinstall:重新安装
search:查找

yum仓库配置文件为server.repo文件,手动创建
vim /etc/yum.repos.d/server.repo
[Base]
name=RHEL5 Server
baseurl=ftp://172.16.0.1/pub/Server
enabled=1
gpgcheck=0

[VT]
name=RHEL5 VT
baseurl=ftp://172.16.0.1/pub/VT
enabled=1
gpgcheck=0

或者写成本地目录:
vim /etc/yum.repos.d/server.repo
[Base]
name=RHEL5 CDROM Server
baseurl=file://media/cdrom/Server
enabled=1
gpgcheck=0

如何创建yum仓库:
yum install createrepo
创建一个本地目录/yum/VT,将CDROM里VT下的内容拷贝到本地目录下,然后写配置文件到本地路径
[VT]
name=VT
baseurl=file:///yum/VT
enabled=1
gpgcheck=0

使用createrepo /yum/VT/ 命令重新创建一下yum源,完成后可以完成依赖关系的文件创建,才可以正常使用本地yum源
还需要
cp comps-rhel5-vt.xml /root 拷贝依赖关系文件到本地
createrepo -g /root/comps-rhel5-vt.xml /yum/VT/ 再次创建yum源,这样依赖关系yum源文件就指定到了root目录下的本地配置文件

RPM安装:
二进制格式;
源程序-->编译-->二进制格式
有些特性是编译选定的,如果编译未选定此特性,将无法使用
rpm包的版本会落后于源码包,甚至落后很多;bind-9.8.7,bind-9.7.2

定制:手动编译安装

编译环境,开发环境
开发库,开发工具

linux:c语言开发
GNU软件:c语言
C环境,C++
纯静态语言
C开发工具gcc:GNU C Complier,C
C++开发工具g++:

make:项目管理工具,
makefile:定义了make(调用gcc,g++)按何种次序去这些源程序文件中的源程序

automake,--> makefile.in --> makefile
autoconf,--> configure 用户选择启用和禁用程序特性

make install 编译好的文件放置相应的目录中

编译安装的三步骤:
前提:准备开发环境(编译环境)
安装“Development Tools"和”Development Libraries“ “Compatibility libraries”
使用yum grouplist 命令查看上面的工具是否已安装,安装后才具备编译环境
#tar
#cd 解压源程序目录下
#./configure
--help
--prefix=/path/to/somewhere
--sysconfdir=/PATH/TO/CONFFILE_PATH
功能:
1、让用户选定编译特性;
2、检查编译环境;
#make
#make install

1、修改PATH环境变量,以能够识别此程序的二进制文件路径;
修改/etc/profile文件
在/etc/profile.d目录建立一个以.sh为后缀的文件,在里面定义export PATH=$PATH:/usr/local/apache/bin
2、默认情况下,系统搜索库文件的路径/lib,/usr/lib;要增添额外搜寻路径;
在/etc/ld.so.conf.d/中创建.conf为后缀的文件,而后把要增添的路径直接写至此文件中;
#ldconfig 重新搜寻库文件
-v:显示重新搜寻库文件的过程
vim /etc/ld.so.conf.d/httpd.conf 创建好httpd.conf文件后填写一下内容:
/usr/local/apache/lib
再使用ldconfig -v|grep apr 会看到多出一条 libaprutil-1.so.0 -> libaprutil-1.so.0.2.7
3、头文件:输出给系统
默认:/usr/include
增添头文件搜寻路径,使用链接进行;
两种方式:
ln -s /usr/local/apache/include/* /usr/include/ 或 ln -s /usr/local/apache/include /usr/include/httpd
4、man文件路径:默认安装在--prefix指定目录下的man目录:/usr/share/man
1、man -M /PATH/TO/MAN_DIR COMMAND 例:man -M /usr/local/apache/man htpasswd
2、/etc/man.config文件中的MANPATH指定了man命令的环境变量路径 例:在/etc/man.config文件中加入MANPATH /usr/local/apache/man

netstat命令:网络状态监测
-r:显示路由表
-n:以数字方式显示
-t:建立的TCP连接
-u:建立的UDP连接
-l:显示监听状态的连接
-p:显示监听指定的套接字的进程的进程号及进程名

写一个脚本完成以下功能
说明:此脚本能于同一个repo文件中创建多个yum源的指向;
1、接受一个文件名作为参数,此文件存放至/etc/yum.repos.d目录中,且文件名以.repo为后缀,要求此文件不能实现存在否则报错;
2、在脚本中,提醒用户输入repo id;而后以repo文件的格式将其保存至指定文件中;
3、repo name以及baseurl的路径,而后以repo文件的格式将其保存至指定文件中;
4、enabled默认为1,而gpgcheck默认设定为0;
5、此脚本会循环执行多次,除非用户为repo id指定为quit;

vim mkrepo.sh
#!/bin/bash
#
REPOFILE=/etc/yum.repos.d/$1

if [ -e $REPOFILE ]; then
echo "$1 exists."
exit 3
fi

read -p "Repository ID:" REPOID
until [ $REPOID == 'quit' ]; do
echo "[$REPOID]" >> $REPOFILE
read -p "Repository name:" REPONAME
echo "name=$REPONAME" >> $REPOFILE
read -p "Repository Baseurl:" REPOURL
echo "baseurl=$REPOURL" >> $REPOFILE
echo -e 'enabled=1\ngpgcheck=0' >> $REPOFILE
read -p "Repository ID:" REPOID
done

echo "hello,world."

循环:while,until,for

break:中断,提前退出循环
continue:提前结束本轮循环,而进入下一轮循环;

计算1000以内所有整数的和,但当SUM值大于5000时就不再加
vi sum.sh

#!/bin/bash
#
declare -i SUM=0

for I in {1..1000}; do
let SUM+=$I
if [ $SUM -gt 5000 ]; then
break
fi
done
echo $I
echo $SUM

while的特殊用法一:
while :;do

done
无限循环

while的特殊用法二:
while read LINE; do 注:读取一个文件,每读取一行就放在变量LINE中

done < /PATH/TO/SOMEFILE 注:一定要给出读取的文件路径

写一个脚本:
1、判断一个指定的bash脚本是否有语法错误;如果有错误,则提醒用户键入Q或q无视错误并退出,其他任何键可以通过vim打开这个指定脚本;
2、如果用户通过vim打开编辑后保存退出时仍然有错误,则重复第1步中的内容;否则,就正常关闭退出
使用方法,syntax.sh为判定脚本,a.sh是被判定语法的脚本
执行:syntax.sh a.sh

bash -n $1 回复状态为0表示没有语法错误,否则就打开脚本

vi syntax.sh

#!/bin/bash
#
until bash -n $1 &>/dev/null; do
read -p "Syntax error,[Qq] to quit,others for editing:" CHOICE
case $CHOICE in
q|Q)
echo "Something wrong,quiting,"
exit 5
;;
*)
vim + $1
;;
esac
done

脚本编程之函数;
function:功能
代码重用的概念,同一个功能和代码多次用到可以独立出来写成一个代码模块,之后重复使用中调用这个代码模块即可

库:so,能够被多个进程调用

脚本例子:

vim diskusage.sh

#!/bin/bash
#
cat << EOF
d|D} show disk usages
m|M) show memory usages
s|S) show swap usages
q|Q) quit.
EOF

read -p "Your chioce: " CHOICE

until [ $CHOICE == 'q' -o $CHOICE == 'Q' ]; do
case $CHOICE in
d|D} df -lh ;;
m|M) free -m |grep "^Mem" ;;
s|S) free -m |grep "^Swap" ;;
q|Q) echo "quit"; exit 0 ;;
*) read -p "Your chioce,again: " CHOICE ;;
esac
read -p "Your chioce: " CHOICE
done


bash脚本中定义函数:把其中某个功能的代码封装起来起一个名字,而后在后面需要用到代码的时候调用他即可

定义一个函数的方法有两种:
第一种:
function FUNCNAME {
command
}

第二种:
FUNCNAME () {
command
}
比如上面的脚本用函数:
vim showmenu.sh
#!/bin/bash
#
function SHOWMENU {
cat << EOF
d|D} show disk usages
m|M) show memory usages
s|S) show swap usages
q|Q) quit.
EOF
}
#调用函数就把定义的函数名写出来即可
SHOWMENU

上面的脚本也可以写为
vim showmenu.sh
#!/bin/bash
#
SHOWMENU() {
cat << EOF
d|D} show disk usages
m|M) show memory usages
s|S) show swap usages
q|Q) quit.
EOF
}

SHOWMENU

自定义执行状态返回值:
return #
取值范围:0-255

vim adduser.sh
#!/bin/bash
#
#定义函数ADDUSER为如果hadoop用户不存在则添加用户并且给用户定义与用户名一样的密码,执行状态定义为0,否则执行状态定义为1,给出执行状态结果。如果用户不存在创建了用户返回值则为0,反之为1.
ADDUSER () {
USERNAME=hadoop
if ! id -u $USERNAME &> /dev/null; then
useradd $USERNAME
echo $USERNAME | passwd --stdin $USERNAME &>/dev/null
return 0
else
return 1
fi
}

ADDUSER
if [ $? -eq 0 ]; then
echo "add user finished."
else
echo "Failuer."
fi

或者执行多个用户添加:
#!/bin/bash
#
ADDUSER () {
USERNAME=$1
if ! id -u $USERNAME &> /dev/null; then
useradd $USERNAME
echo $USERNAME | passwd --stdin $USERNAME &>/dev/null
return 0
else
return 1
fi
}

for I in {1..10}; do
ADDUSER user$I
if [ $? -eq 0 ]; then
echo "add user$I finished."
else
echo "add user$I Failuer."
fi
done

接受参数的函数;
./a.sh m n
$1:m
$2:n
跟脚本调用参数一样,函数也是如此
TWOINT 5 6
$1:5
$2:6

#!/bin/bash
#
TWOSUM() {
echo $[$1+$2]
}

SUM=`TWOSUM 5 6`
echo $SUM

或者执行多个连续相加
#!/bin/bash
#
TWOSUM() {
echo $[$1+$2]
}

for I in {1..10}; do
let J=$[$I+1]
echo "$I plus $J is `TWOSUM $I $J`"
done

写一个脚本:判定192.168.0.200-192.168.0.254之间的主机哪些在线。需求:
1、使用函数来实现一台主机的判定过程;
vim hostonline.sh

#!/bin/bash
#
PING() {
for I in {200..254}; do
if ping -c 1 -W 1 192.168.0.$I &> /dev/null; then
echo "192.168.0.$I is up."
else
echo "192.168.0.$I is down."
fi
done
}

PING
2、在主程序中来调用此函数判定指定范围内的所有主机的在线情况。
vim hostonline2.sh

#!/bin/bash
#
PING() {
if ping -c 1 -W 1 $1 &> /dev/null; then
echo "$1 is up."
else
echo "$1 is down."
fi
}

for I in {200..254}; do
PING 192.168.0.$I
done

for I in {200..254}; do
PING 172.16.100.$I
done

进程管理
根据程序变化而不断增长的内存叫做堆内存

进程属性:
进程号
内存空间:VSZ:虚拟内存大小,RSS:常驻内存集,物理内存空间,不包含被交换出去的内存集。
用户
父进程
CPU 运行时间

并行编程模型:单进程多线程
process
thread:被分解的进程子体

进程、线程模型:
Stopped:停止状态,不会被调度
Ready:就绪,排队等待CPU
Executing:正在运行
Uninterruptible sleep:不可终端的睡眠
Interruptible sleep:可中断睡眠
Zombie:僵尸进程,导致内存泄漏的一种情况

系统内核生成的第一个进程为init,其余进程均为init的子进程

通过pstree命令可以查看到进程结构

进程优先级关系:
linux进程优先级从0到139,140种优先级变化,数字越小优先级越高

100-139:由用户可控制
0-99:内核调整

O标准:
O(1):无论队列有多长挑选一个时间一样的,性能最佳
O(n):队列越长所需时间越长的线性增长
O(logn):队列长度所需log的时间方式增长
O(n^2):随着队列增长呈现快速增长
O(2^n):随着队列增长呈现成倍增长

优先级高:
1、获得更多的CPU运行时间;
2、更优先获得运行的机会;

100-139用户可控级别:
nice值:优雅的,友好的,每个进程拥有一个nice值
-20到19对应100-139,调整nice值来调整对应的优先级
例:0对应120,-5对应116,nice值越小优先级越高
普通用户仅能够调大自己的进程nice值
管理员可以随意调整

PID:process ID
/proc目录下,以数字命名的目录均为进程PID目录,每个目录对应一个进程,保存进程相关属性信息
init进程号永远为1,其他进程均为init的子进程

进程分类:
跟终端相关的进程
跟终端无关的进程

进程状态:
D:不可中断的睡眠
R:运行或就绪
S:可中断的睡眠
T:停止
Z:僵尸态
<:高优先级进程
N:低优先级进程
+:前台进程组中的进程
l:多线程进程
s:会话进程的首进程

ps命令:process state
SsyV风格:选项需加-
-elF
-e:显示所有线程
-l:长格式 PRI表示优先级,NI表示nice值
-F:显示更多详细信息
BSD风格:选项无需-
aux
a:显示所有跟终端有关的进程
u:显示启动进程的用户
x:显示所有跟终端无关的进程
注:加中括号的进程属于内核进程

-o PROPERTY1,PROPERTY2 指定要显示的字段。 例:ps -o pid,comm,ni 默认只显示前台进程,需要加ax

pstree:显示当前系统上的进程树

pgrep:以grep的风格指定符合某种特性的进程
-u:指定某个用户运行的进程

pidof:按照进程名找到进程号

top:显示当前系统上进程状态(动态)5秒更新一次
load average:平均负载,三个数值分别是表示1分钟,5分钟,15分钟的平均队列长度,值越小CPU负载越低
Tasks:进程运行状态数量,total总数量,running运行数量,sleeping睡眠状态数量,stopped停止状态数量,zombie僵尸状态数量。
CPU:每个CPU负载情况,us用户占据的百分比,sy系统占据的比例,ni表示nice值调整后影响的cpu比例,id空闲比例,wa等待IO完成所占据的时间,hi硬件中断占据的时间,si软件中断占据的时间,st被偷走的时间(虚拟化中常用)
Mem:内存,total总数,used使用数,free空闲数,buffers数量(均为物理内存)
Swap:交换分区,total总数,used使用数,free空闲数,cached数量(均为物理内存)
动态进程的信息:
PID进程号,USER用户,PR表示实时优先级,NI表示nice值,VIRT虚拟内存集,RES常驻内存集,SHR共享内存大小,S表示状态,%CPU占用CPU百分比,%MEM占用内存百分比,TIME+表示运行时长真正占据CPU的时长,COMMAND表示进程名称

top命令执行时使用参数:
M:根据主流内存大小进行排序
P:根据CPU使用百分比进行排序
T:根据累计时间进行排序

l:是否显示平均负载和启动时间
t:是否显示进程和CPU状态相关信息
m:是否显示内存相关信息

c:是否显示完整的命令行信息
q:退出top
k:终止某个进程

top命令后跟参数:
-d #:指定延迟时长,默认每隔5秒刷新1次,可以更改间隔秒数,例如:top -d 1 每1秒刷新一次
-b:以批处理模式,顺序翻屏式显示。例如top -d 1 -b
-n #:在批处理模式下,定义只显示几屏

vmstat:系统状态查看命令,使用样例:vmstat 1 5 注解:动态显示系统状态,1为每隔1秒显示1次,5为显示5次后结束
procs:进程相关内容
r:运行队列长度
b:阻塞队列长度
memory:内存相关内容
swpd:交换大小
free:空闲内容
buff:用于缓冲的
cache:用于缓存的
swap:动态显示交换空间使用情况
si:从物理内存进入swap分区的页面数量
so:从swap分区又调回物理内存的页面数量
io:IO读写操作相关内容
bi:有多少磁盘块被调入到了物理内存
bo:有多少磁盘块从内存中同步到了磁盘中
system:系统内核相关内容
in:进程中断个数
cs:上下文进程切换的次数
cpu:CPU性能使用相关内容
us:用户占用cpu百分比
sy:系统内核占用cpu百分比
id:空闲cpu百分比
wa:等待IO
st:被偷走的cpu百分比

free:查看内存以及swap使用情况
-m:

kill:结束进程
-l:显示出所有可用信号,实现进程相互通信
1)SIGHUP:让一个进程不用重启,就可以重读其配置文件,并让其新的配置文件生效。例:kill -1 PID 或 kill -SIGHUP PID
2)SIGINT:Ctrl+C相同,中断一个进程 例:kill -2 PID 或 kill -INT PID
9)SIGKILL:杀死一个进程,强行结束进程 例:kill -9 PID 或 kill -KILL PID
15)SIGTERM:终止一个进程,进程运行完毕后结束 例:kill -15 PID 或 kill -SIGTERM PID

killall COMMAND(进程名):杀死所有主进程以及子进程

pkill COMMAND(进程名):与killall近似

进程间通信(IPC:Inter Process Communication)
共享内存
信号:Signal
旗语:Semaphore

调整未启动进程的nice值,在启动时调整nice值:
nice -n NI(nice值) COMMAND

调整已经启动的进程的nice值:
renice NI(nice值) PID

前台:占据了命令提示符
后台:启动之后,释放命令提示符,后续的操作在后台完成
命令结尾处使用&符号即可后台运行

前台-->后台:
Ctrl+z:把正在前台的作业送往后台,但进程会停止
bg:让停止的命令在后台继续运行:
bg [%JOBID] 百分号用于区别于进程号
jobs:查看后台的所有作业。作业号,不同于进程号
+:命令将默认操作的作业
-:命令将第二个默认操作的作业
fg:将后台的作业调回前台
fg [%JOBID] 百分号用于区别于进程号
kill:终止某个作业
kill %JOBID
COMMAND &:让命令在后台执行

uptime:显示结果为:当前时长,已运行时长,当前多少用户登录,平均负载,三个数值分别是表示1分钟,5分钟,15分钟的平均队列长度,值越小CPU负载越低

/proc/meminfo和cpuinfo均是显示cpu和内存的相关信息


Linux系统启动流程

PC:OS(Linux)

POST自检-->BIOS(Boot-Sequence)-->MBR(bootloader,446k,大于2T以后就要更换GBG格式)-->Kernel(硬件资源调度)-->init(用户空间的管理工作)-->(ROOTFS)/sbin/init(/etc/inittab)

kernel作用:
文件系统
进程管理
内存管理
网络管理
安全功能
驱动程序

内核设计风格:

单内核:所有内核功能全部装载进一个进程中运行,Linux属于单内核(LWP:轻量级进程)
核心:ko(kernel object)
核心:动态加载 内核模块
内核模块:/lib/modules/“内核版本号命名的目录”
内核名称:/lib/modules/vmlinuz-2.6.32
内核访问根目录过程(需要创建临时的根文件系统):
chroot:切换根使用,将一个临时目录当做根目录使用,需要有bin/bash文件以及lib依赖库才可以完成切换
chroot /PATH/TO/TEMPTOOR [COMMAND..]
ldd:显示共享库依赖关系。例如:ldd /bin/bash 列出与bash相关的库,将依赖库拷贝到要切换的lib目录下即可切换
redhat6:ramfs-->initramfs
switch_root:红帽5的根切换命令
redhat5:ramdisk-->initrd

微内核:根据功能分别创建不同的子内核进程进行工作,Windows,Solaris(线程)

启动的服务不同:
运行级别:0-6 共7个级别
0:halt 关机
1:single user mode 单用户模式,直接以管理员身份切入,类似于windows安全模式。 s,S,single都可以表示单用户
2:multi user mode 多用户模式,no NFS 不启用nfs
3:multi user mode,text mode 只有命令行界面不启动图形界面
4:reserved 保留级别,尚且未定义内容
5:multi user mode,graphic mode 启动图形界面
6:reboot 重启

详解启动过程:
BootLoader(MBR)
LILO:Linux Loader
GRUB:GRand Unified Bootloader
Stage1:MBR
Stage1.5:识别不同类型的文件系统
Stage2:/boot/grub/Stage2关联同目录下的grub.conf配置文件

grub.conf文件详解:

default=0 #设定默认启动的title编号,从0开始编号
timeout=5 #等待用户选择的超时时长,单位是秒
splashimage=(hd0,0)/grub/splash.xpm.gz #指定grub背景图片
hiddenmenu #隐藏菜单
password --md5 加密密码串 #添加此项可以给grub加密码访问,加--md5可以使用加密密码,使用命令grub-md5-crypt生成加密密码
#title是不同的操作系统的引导标识,可以多个title信息
title Red Hat Enterprise Linux (2.6.32-358.el6.x86_64) #内核标题,或操作系统名称,字符串,可自由修改
root (hd0,0) #内核文件所在的设备;对grub而言,所有类型硬盘一律为hd,光盘为cdrom;hd后面表示第几块磁盘,第几块分区
kernel /vmlinuz-2.6.32-358.el6.x86_64 ro root=UUID=a6a649bb-bdde-4e9e-9548-c1e9c5e591e8 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet #内核文件路径及传递给内核的参数
initrd /initramfs-2.6.32-358.el6.x86_64.img #ramdisk文件路径
password --md5 加密密码串 #密码加在这里启动此内核就需要密码,上面是编辑时输入密码

gimp是linux下的图形编辑软件

查看运行级别:
runlevel:
who -r:也可以显示运行级别
查看内核release号:
uname -r


安装或修复grub stage1:
# grub
grub> root (hd0,0) #指定安装位置

grub> setup (hd0) #安装命令并指定安装到的磁盘,只写磁盘即可

grub> quit #退出

安装grub第二种方式:
# grub-install --root-directory=/path/to/boot's_parent_dir /path/to/device #这里指定的root-directory指定的目录一定是分区时boot所在的位置,最后指定硬盘
重新编辑grub.conf文件在对应的boot父目录下
安装命令执行后要执行sync命令进行同步

在--root-directory=/path/to/boot's_parent_dir指定的grub目录下创建grub.conf文件

default=0 #设定默认启动的title编号,从0开始编号
timeout=5 #等待用户选择的超时时长,单位是秒
splashimage=(hd0,0)/grub/splash.xpm.gz #指定grub背景图片
hiddenmenu #隐藏菜单

title Red Hat Enterprise Linux (2.6.32-358.el6.x86_64)
root (hd0,0)
kernel /vilinux #非真实
initrd /initrd.img #非真实

保存退出后要使用sync从内存同步至硬盘中,否则重启就无效了

如果不小心将grub.conf配置文件删除,如何修复:
删除配置文件重启后会进入grub> 引导界面按照如下操作恢复
grub> find (hd0,0)/ #输入到这里敲tab键查看是否有内核文件,确认后执行下面的命令
grub> root (hd0,0) #指定root
grub> kernel /vmlinuz-2.6.18-308.el5 #指定kernel
grub> initrd /initrd-2.6.18-308.el5.img #指定initrd
grub> boot #重新引导系统

kernel初始化的过程:
1、设备探测
2、驱动初始化(可能会从initrd或initramfs文件中装载驱动模块)
3、以只读方式挂载根文件系统
4、装载第一个进程init(PID:1) /sbin/init:(/etc/inittab)
红帽6以后使用upstart(ubuntu)代替init进程,d-bus,event-driven事件驱动的基于d-bus的
还有systemd进程,均支持并行启动多个进程

inittab文件详解:
id:runlevels:action:process
id:标识符;
runlevels:在哪个级别运行此行;
action:在什么情况下执行此行;
process:要运行的程序;

si::sysinit:/etc/rc.d/rc.sysinit
OS初始化
si:标识符
##:运行级别为空则是所有运行级别
sysinit:系统启动时
运行程序为:/etc/rc.d/rc.sysinit
/etc/rc.d/rc.sysinit所完成的任务:
1、激活的udev和selinux
2、根据/etc/sysctl.conf文件,来设定内核参数;
3、设定系统时钟;
4、装载键盘映射;
5、启用交换分区;
6、设置主机名;
7、根文件系统检测,并以读写方式重新挂载
8、激活软RAID和LVM设备;
9、启用磁盘配额;
10、根据/etc/fstab,检测并挂载其他文件系统;
11、清理过期的锁和PID文件;

ACTION:
initdefault:设定默认运行级别
sysinit:系统初始化
wait:等待级别切至此级别时执行
ctrl+alt+del:重启
powerfail:断电2分钟后关机
powerokwait:断电2分钟内恢复,取消关机指令
respawn:一旦程序终止,会重新启动

l0:0:wait:/etc/rc.d/rc 0
rc0.d/
K*
stop
S*
start
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6

所有链接脚本全部存在:
/etc/rc.d/init.d,/etc/init.d

服务类脚本:
SysV: /etc/rc.d/init.d
start|stop|restart|status
reload|configtest

虽然前面有井号但是脚本会被读取
# chkconfig runlevls SS KK:第一组runlevls默认启动级别,第二组SS启动优先次序,第三组KK关闭优先次序
当chkconfig命令来为此脚本在rc#.d目录下创建链接时,runlevels表示默认创建为S*开头的链接,runlevels:-表示,没有级别默认为S*开头的链接除此之外的级别都默认创建为K*开头的链接;
S后面的启动优先级为SS所表示的数字;K后面关闭优先次序为KK所表示的数字
# description:用于书名此脚本的简单功能;\,续行

for I in /etc/rc3.d/K*; do
$I stop
done

for I in /etc/rc3.d/S*; do
$I start
done

##:关闭或启动的优先次序,数据越小越优先被选定

chkconfig:
--list:列出当前系统上的所有服务以及各运行级别的启动关闭状态,独立守护进程;
--add SERVICE_NAME:加到chkconfig服务列表中
--del SERVICE_NAME:删除某个chkconfig服务
--level 24 SERVICE_NAME off|on :指定某些级别下SERVICE启用或关闭
如果省略级别指定不填写,默认为2345级别;

样例脚本:
vim myservice
#!/bin/bash
#
# chkconfig:2345 77 22 #SS和KK最好加起来是99,不强制,不是99也无所谓
# description:Test SERVICE_NAME
#
LOCKFILE=/var/lock/subsys/myservice

status() {
if [ e $LOCKFILE ]; then
echo "Running.."
else
echo "Stopped.."
fi
}

usage() {
echo "`basename $0` {start|stop|restart|status}"
}

case $1 in
start)
echo "Starting.."
touch $LOCKFILE ;;
stop)
echo "Stopped.."
rm -f $LOCKFILE &> /dev/null
;;
restart)
echo "Restarting.." ;;
status)
status ;;
*)
usage ;;
esac

设置开机启动:
在/etc/rc.local文件中加入命令即可
此文件对应的是/etc/rc.d/rc.local:系统最后启动的一个服务,准确说应该是执行的一个脚本

REDHAT-5
/etc/inittab的任务:
1、设定默认运行级别;
2、运行系统初始化脚本;
3、运行指定级别对应的目录下的脚本;
4、设定Ctrl+Alt+Del组合键的操作;
5、定义UPS电源在电源故障/恢复时执行的操作
6、启动虚拟终端(2345级别)
7、启动图形终端(5级别)

守护进程的类型:
独立守护进程:
xinetd:超级守护进程,需要关联运行级别,负责对瞬时守护进程的管理,是瞬时守护进程的代理人
瞬时守护进程:不需要关联至运行级别
安装xinetd进程并启动后,使用chkconfig --list最下方可以看到xinetd服务下的瞬时启动进程状态
使用chkconfig SERVICE_NAME on 即可启动

核心:/boot/vmliuz-version
内核模块(ko):/lib/modules/version
内核设计:
单内核
模块化设计
微内核:

装载模块命令:
insmod
modprobe

www.kernel.org

用户空间访问、监控内核的方式:
/proc,/sys与内核打交道的目录
/proc/sys:/proc目录大多都是只读文件,/proc/sys目录中的文件很多是可读写的,可修改内核参数
向内核文件中写文件不要vim打开,非文本文件,需要使用如:echo 1 > /proc/sys/vm/drop_caches写入参数,这里举例的命令是清除free -m中buffers和cached数值的
/proc/sys/kernel:目录下hostname文件,cat此文件与当前主机名一至,echo 主机名到此文件也可以重命名主机名。
/sys:某些文件可写


设定内核参数值的方法:
echo VALUE > /proc/sys/TO/SOMEFILE

sysctl命令:
sysctl -W kernel.hostname=“重命名的主机名” 同 echo 重命名主机名 > /proc/sys/kernel/hostname
sysctl -w vm.drop_caches=1 同 echo 1 > /proc/sys/vm/drop_caches

能立即生效,但无法永久有效。
永久有效,但无法立即生效:/etc/sysctl.conf
将需要设定的内核参数写入此文件方法使用sysctl命令的方式写入

cat /proc/sys/net/ipv4/ip_forward 此文件是说如果此服务器有两块网卡,这两块网卡之间是否可以转发流量包的,允许把本机当作路由器来用
0 表示不可用
1 表示可用

vim /etc/sysctl.conf
将net.ipv4.ip_forward = 0 改为 = 1 保存退出
重启后就会生效
立即生效使用:
sysctl -p :重读配置文件 或者 sysctl -w net.ipv4.ip_forward = 1
sysctl -a:显示所有内核参数及其值

内核模块管理:
lsmod:列出当前内核中已装载的模块,以及被哪个用户调用了几次
modprobe MOD_NAME:装载某个模块
modprobe -r MOD_NAME:卸载某个模块
modinfo MOD_NAME:查看模块的具体信息
filename:模块对应的文件路径
alias:模块别名
license:模块许可
descriprion:模块描述
module_sig:签名parm:额外的参数
depends:依赖的模块
insmod /PATH/TO/MODULE_FLES:装载模块
rmmod MOD_NAME:移除模块
depmod /PATH/TO/MODFILE_DIR:生成模块间的依赖关系,生成后的文件会保存在这个目录中

内核中的功能除了核心功能之外,在编译时,大多功能都有三种选择:
1、不使用此功能;
2、变异成内核模块;
3、编译进内核;

如何手动编译内核:
使用yum grouplist查看 development libraries和development tools是否已安装,如果未安装需要安装后再升级
下载好要升级的内核版本文件
将下载的内核安装包解压至/usr/src目录下,如:tar xf linux-2.6.28.10.tar.gz -C /usr/src
创建链接 ln -sv linux-2.6.28.10 linux 将内核解压的源码包链接为linux目录
内核模块安装选择:
图形编译安装:
make gconfig:Gnome桌面环境使用,需安装图形开发库:GNOME Software Development
make kconfig:KDE桌面环境,需安装图形开发库:KDE Software Development
yum grouplist查看KDE或GNOME的开发库是否已安装

文本菜单编译安装:
make menuconfig:以菜单形式进行模块选择,连续敲击空格键选择,选择完成后使用Esc退出,最后选择Yes保存并退出
选择完后再/usr/src/linux目录下会生成一个.config的文件,就是你所选择的内核模块配置信息
使用make命令进行内核编译过程
在/boot/config-2.6.18-208.el5的文件,是之前内核编译的配置文件,在编译前把此文件拷贝到/usr/src/linux/.config 进行覆盖,再执行make menuconfig就是在之前内核安装配置基础上进行功能编辑了。此方法最为保险

make编译完成之后
先使用make modules_install安装内核模块
然后再使用make install进行安装

注意:编译内核时尽量不要使用远程连接完成,远程断开即编译就会停止,如果使用远程连接编译安装内核,则需安装一个screen工具,yum install screen;可以在当前窗口中模拟很多窗口,安装后使用screen命令即可打开多个界面
screen命令:
screen -ls:显示已经建立的屏幕
screen:直接打开一个新的屏幕
Ctrl+a松开后再摁d:拆除屏幕
screen -r ID:还原回某个屏幕
exit:退出

二次编译时清理:
make clean:清理之前编译好的二进制模块
make mrproper:清理之前编译所残留的任何操作,包括.config文件,所以执行此命令之前要把.config备份一下

在一个操作系统下添加一块硬盘重新创建一个操作系统:
grub-->kernel-->initrd-->ROOTFS(/sbin/init,/bin/bash)
先挂载一块磁盘,并进行fdisk分区
内核加启动分区:20M
根分区:512M
保存退出,partprobe /dev/hda
mke2fs -j /dev/hda1和2
创建两个挂载目录:
mkdir /mnt/{boot,sysroot}
mount /mnt/boot和sysroot
安装grub:
grub-install --root-directory=/mnt /dev/hda
拷贝系统内核:
cp /boot/vmlinuz-2.6.18-308.el5 /mnt/boot/vmlinuz
创建initrd:
mkinitrd initrd文件路径 内核版本号
mkinitrd /boot/initrd-`uname -r`.img `uname -r`
查看内核文件类型为gzip文件
file initrd-2.6.18-308.el5.img
cp /boot/initrd-2.6.18-308.el5.img /root
mv initrd-2.6.18-308.el5.img -2.6.18-308.el5.img.gz
gzip -d initrd-2.6.18-308.el5.img.gz
再看文件类型已经变为ASCII文件了
file initrd-2.6.18-308.el5.img
展开内核文件:
cpio -id <../initrd-2.6.18-308.el5.img <../表示父目录中的
还可以用下面命令,免去解压复制之前的繁琐操作
zcat /boot/initrd-2.6.18-308.el5.img | cpio -id
编辑init脚本文件:
vim init
找到mkrootdev选项中 把后面的路径改为你要创建的路径/dev/hda2即可
把resume开头的关于SWAP的选项注释掉
重新打包为内核镜像:
当前目录下执行
find . |cpio -H newc --quiet -o | gzip -9 > /mnt/boot/initrd.gz 注:找到本目录下所有文件归档-H newc指定类型--quient表示静默模式,-o表示归档复制,使用管道送给gzip -9 >最大压缩比输出重定向为gz文件,最终文件3.4M
创建grub配置文件:
在/mnt/boot/grub下创建grub.conf文件
vim /mnt/boot/grub/grub.conf
default=0
timeout=5
title Test Linux (Magedu Team)
root (hd0,0)
kernel /vmlinuz
initrd /initrd.gz
编辑根文件系统:
cd /mnt/sysroot
mkdir proc sys dev etc/rc.d lib bin sbin boot home var/log usr/{bin,sbin} root tmp -pv
cp /sbin/init /mnt/sysroot/sbin/
cp /bin/bash /mnt/sysroot/bin/bash
ldd /sbin/init 按照提示结果cp库中没有的文件
cp /lib/libsepol.so.1 /mnt/sysroot/lib/
cp /lib/libselinux.so.1 /mnt/sysroot/lib/
cp /lib/libc.so.6 /mnt/sysroot/lib/
cp /lib/libdl.so.2 /mnt/sysroot/lib/
ldd /bin/bash
cp /lib/libtermcap.so.2 /mnt/sysroot/lib/
chroot /mnt/sysroot 试着切换至新系统的根目录,但是有些命令还无法执行
sync 执行以下同步写入磁盘
创建inittab文件
vim /mnt/sysroot/etc/inittab
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
创建rc.sysinit脚本文件
vim /mnt/sysroot/etc/rc.d/rc.sysinit
#!/bin/bash
#
echo -e "\tWelcom to \033[31mMageEdu Team\033[0m Linux."
/bin/bash
保存退出
chmod +x /mnt/sysroot/etc/rc.d/rc.sysinit
sync 同步配置

创建新的虚拟机,将此虚拟硬盘挂载上,看是否可以正常引导启动linux系统

系统正常启动,但是无法执行ls等常用命令,回到原linux系统进行ls的补全
登录系统后执行:
ldd /bin/ls
出现依赖的动态链接库文件,将依赖的库文件cp到相应的/mnt/sysroot/lib/目录下

bash脚本的变量截取用法:
FILE=/usr/local/src
${parameter#*word} 变量从左到右截取第一个以/为分隔符的部分,也就是去除第一个/后面的部分
${parameter##*word} 变量从最后一个/为分隔符从左到右的部分
如:${FILE#*/} : usr/local/src
${FILE##*/} : src

${parameter%word*} 变量与上面相反从右往左顺序查找分隔符,第一个分隔符往左的全都显示
${parameter%%word*} 变量从右往左找到最后一个分隔符往左的内容显示
如:${FILE%/*} : /usr/local/
${FILE%%/*} : 为空因为从右往左最后一个/前面没有任何字符

写一个脚本协助完成将动态链接库文件全部拷贝到新创建的系统lib目录下
vim bincopy.sh
#!/bin/bash
#
DEST=/mnt/sysroot
libcp() {
LIBPATH=${1%/*}
[ -d $DEST$LIBPATH ] && mkdir -p $DEST$LIBPATH
[ ! -e $DEST$(1) ] && cp $1 $DEST$LIBPATH echo "copy lib $1 finished."
}

bincp() {
CMDPATH=${1%/*}
[ ! -d $DEST$CMDPATH ] && mkdir -p $DEST$CMDPATH
[ ! -e $DEST$(1) ] && cp $1 $DEST$CMDPATH

for LIB in `ldd $1 |grep -o "/.*lib\(64\)\{0,1\}/[^[:space:]]\{1,\}"`
libcp $LIB
done
}

read -p "Your command: " CMD
until [ $CMD == 'q' ]; do
! which $CMD && echo "Wrong command" && read -p "Input againe" CMD && continue
COMMAND=`which $CMD |grep -v "^alias"|grep -o "[^[:space:]]\{1,\}"`
bincp $COMMAND
echo "copy $COMMAND finished."
read -p "Continue:" CMD
done
保存退出
脚本执行后按照提示输入相关命令即可将对应动态库全部拷贝到新系统中

使用modinfo mii 和 pcnet32 查看filename路径及文件将其cp到/mnt/sysroot/lib/modules/目录下
sync:同步一下
执行bincopy.sh脚本将lsmod命令相关库拷贝过来
编辑系统启动脚本添加以下内容
vim /mnt/sysroot/etc/rc.d/rc.sysinit
#!/bin/bash
#
echo -e "\tWelcom to \033[31mMageEdu Team\033[0m Linux."
insmod /lib/modules/mii.ko
insmod /lib/modules/pcnet32.ko
ifconfig eth0 172.16.100.13/16
ifconfig lo 127.0.0.1/8
/bin/bash
保存退出
这样系统就可以认到网络设备了

系统启动流程:

POST-->BIOS(Boot sequence)-->BootLoader(MBR)-->kernel(initrd或initramfs)-->init(/etc/inittab,RHEL6:upstart)

RHEL6:
upstart-->init
/etc/inittab
/etc/init/*.conf

/etc/inittab:
设定默认运行级别
系统初始化脚本(/etc/rc.d/rc.sysinit)
运行指定级别的服务脚本
/etc/rc.d/init.d/
/etc/rc.d/rc#.d
rc0.d--rc6.d
K*
S*
00-99:运行次序,数字越小越先被执行
启动虚拟终端
启动图形终端

/etc/rc.d/rc.sysinit:
检测,并且以读写方式重新挂载根文件系统
设定主机名;
检测并挂载fstab中的其他文件系统
启用swap分区
初始化外围硬件设备的驱动程序
根据/etc/sysctl.conf设定内核参数;
激活LVM和RAID设备;
清理过期的锁和PID文件;
装载键映射;

/etc/inittab
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit

/etc/rc.d/rc.sysinit 仅激活了bash
echo
/bin/bash

内核初始化:
硬件探测
装载驱动
挂载根文件系统(rootfs)
启动用户空间中的第一个进程init

让简易系统可以实现以下功能:
1、可以开关机和重启
2、主机名;
3、运行对应级别的服务脚本;
4、启动终端;
5、运行用户;
6、定义但用户级别;
7、装载网卡驱动,启用网络功能;
8、提供一个web服务器;

busybox:1M
Kernel:

RHEL5,RHEL6
定制安装:
自动化安装
定制引导盘

第一步:复制内核
cp /boot/vmlinuz-2.6.18-308.el5 /mnt/boot/vmlinuz
mkdir test
cd test
zcat /boot/vmlinuz-2.6.18-308.el5.img | cpio -id
进入解压后的test目录下,编辑init脚本文件
vim init
找到mkrootdev选项中 把后面的路径改为你要创建的路径/dev/hda2即可
把resume开头的关于SWAP的选项注释掉
DM模块全部注销掉
:.,+20s@^@#@g 注:从当前行向下20行,行首为任意字符的均添加#符号注释
lib目录下删除所有dm开头的文件
rm -f dm-*
制作为
find . | cpio -H newc --quiet -o |gzip -9 > /mnt/boot/initrd.gz
第二步:安装grub
grub-install --root-directory=/mnt /dev/hda
ls /mnt/boot 检验目下是否已经有grub目录
创建grub配置文件:
在/mnt/boot/grub下创建grub.conf文件
vim /mnt/boot/grub/grub.conf
default=0
timeout=5
title MageEdu Linux (2.6.18)
root (hd0,0)
kernel /vmlinuz
initrd /initrd.gz
保存退出
第三步:创建根文件系统:
cd /mnt/sysroot
创建所需目录:
mkdir proc sys dev etc/{rc.d/init.d} lib bin proc sys sbin boot media home var/{log,run,lock/subsys,tmp} usr/{bin,sbin} root tmp opt -pv
创建inittab配置文件:
vim /mnt/sysroot/etc/inittab
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
创建rc.sysinit脚本文件
vim /mnt/sysroot/etc/rc.d/rc.sysinit
#!/bin/bash
#
echo -e "\tWelcom to \033[31mMageEdu Team\033[0m Linux."
/bin/bash
保存退出
chmod +x /mnt/sysroot/etc/rc.d/rc.sysinit
sync 同步配置
第四步:cp相应的命令动态库,因为较多因此我们编写了bincp.sh脚本执行
运行bincp.sh脚本
依次输入command:init、bash、ls等命令
sync同步
chroot /mnt/sysroot 切换系统看一下
使用command:touch、mkdir、rm、mv、cat、mount、vi、chmod、chown、vim、umount、ping、ifconfig、insmod、modprobe、rmmod、route、halt、reboot、shutdown、hostname

sync同步
切换虚拟机

获取可读写权限:
mount -n -o remount,rw / 提示mtab文件只读无法更新
mount -n :挂载时不更新/etc/mtab文件
cat /proc/mounts :可以查看当前系统上所挂载的所有文件系统

第五步:提供关机重启服务
此时,让新系统关机,直接执行halt命令,只是关闭了进程,但无法切断电源
cd /mnt/sysroot
vim etc/rc.d/rc.sysdone
#!/bin/bash
#
sync
sleep 2
sync
exec /sbin/halt -p
保存退出
chmod +x etc/rc.d/rc.sysdone
./bincp.sh 使用此脚本为sync和sleep拷贝库文件
在/mnt/sysroot/etc/inittab中添加下行
l0:0:wait:/etc/rc.d/rc.sysdone
保存退出
sync同步
再切换新系统中启动,使用init 0和halt 均可关机了
重启还需要再
在/mnt/sysroot/etc/inittab中添加下行
l6:6:wait:/etc/rc.d/rc.reboot
保存退出
sync同步
vim etc/rc.d/rc.reboot
#!/bin/bash
#
sync
sleep 2
sync
exec /sbin/reboot
保存退出
mount -n -o remount,rw /
chmod +x etc/rc.d/rc.reboot
sync同步
此时执行init 6或者reboot即可重启

关机和重启脚本
vim /mnt/sysroot/etc/rc.d/init.d/halt
#!/bin/bash
#
case $0 in
*halt)
COMMAND='/sbin/halt -p' ;;
*reboot)
COMMAND='/sbin/reboot' ;;
*)
echo "Only cal this script by *reboot OR *halt;"
;;
esac

case $1 in
start)
;;
stop)
;;
*)
echo "Usage:`basename $0` {start|stop}"
;;
esac

exec $COMMAND
保存退出
chmod +x etc/rc.d/init.d/halt
mkdir rc0.d rc6.d
cd rc0.d
ln -sv ../init.d/halt S99halt
cd rc6.d
ln -sv ../init.d/halt S99reboot
开机自启动执行K*或S*的开启或关闭脚本
vim rc
#!/bin/bash
#
RUNLEVEL=$1

for I in /etc/rc.d/rc$RUNLEVEL.d/K*; do
$I stop
done
for I in /etc/rc.d/rc$RUNLEVEL.d/S*; do
$I start
done
保存退出
chmod +x rc
在inittab中更改两行
l0:0:wait:/etc/rc.d/rc 0
l6:6:wait:/etc/rc.d/rc 6
l3:3:wait:/etc/rc.d/rc 3
cd etc/rc.d/
mkdir rc3.d

创建tserver脚本,显示服务状态
使用bincp.sh脚本加载seq、stty命令
vim init.d/tserver
#!/bin/bash
#
#chconfig:35 66 33
#description:test service script
. /etc/rc.d/init.d/function #将function脚本中定义的函数装载过来
prog=tserver
lockfile=/var/lock/subsys/$prog

start() {
echo "Starting $prog..."
touch $lockfile
[ $? -eq 0 ] && success “Starting $prog" || failure "Starting $prog"
}

stop() {
echo "Stopping $prog ..."
rm -f $lockfile
[ $? -eq 0 ] && success “Stopping $prog" || failure "Stopping $prog"
}

status() {
if [ -f $lockfile ]; then
echo "Running..."
else
echo "Stopping..."
fi
}

usage() {
echo "Usage: $prog {start|stop|status|restart}"

case $1 in
start)
start ;;
stop)
stop ;;
restart)
stop
start
;;
status)
status
;;
*)
usage
exit 1
;;
esac
保存退出
chmod +x /init.d/tserver
cd rc3.d
ln -sv ../init.d/tserver S66tserver
cd rc0.d
ln -sv ../init.d/tserver K33tserver
cd rc6.d
ln -sv ../init.d/tserver K33tserver

第六步:加载终端启动内容
mingetty:启动终端命令/sbin/mingetty
先使用bincp.sh,将mingetty命令和basename命令加载进新系统
cd /mnt/sysroot/bin
ln -s bash sh
继续编辑/mnt/sysroot/etc/inittab添加启动终端命令
1:2345:respawn:/sbin/mingetty --loginprog=/bin/bash tty1
2:2345:respawn:/sbin/mingetty --loginprog=/bin/bash tty2
在执行mingetty时需要执行另外一个程序叫login,表示已登录终端,所以需要添加--loginprog=/bin/bash参数
此时在/mnt/sysroot/etc/rc.d/rc.sysinit脚本中的/bin/bash就可以删除了,因为默认启动终端已经完成bash启动
sync同步
stty命令可以显示串行终端的速率
stty -F /dev/console size 25 80为显示终端大小,横向显示80个字符,纵向显示25个字符
stty -F /dev/console speed 38400为显示终端速率,每秒显示的终端字符数量
使用bincp.sh,将agetty加入新系统中
vim /mnt/sysroot/etc/inittab 更改一下内容
1:2345:respawn:/sbin/agetty -n -l /bin/bash 38400 tty1
2:2345:respawn:/sbin/agetty -n -l /bin/bash 38400 tty2
sync同步
新系统启动提示找不到inittab文件,说明文件系统错乱,系统来回切换的过程中会产生此问题发生,此时来修复文件系统mke2fsck命令可以修复,但是会导致文件丢失;
cd /mnt/sysroot将根目录下的所有文件打包备份
find . |cpio -H newc --quiet -o |gzip > /root/sysroot.gz 备份
fuser -km /dev/hda2
umount /dev/hda2
mke2fs -j /dev/hda2 或者 e2fsck -f /dev/hda2
mount /dev/hda2 /mnt/sysroot
cd /mnt/sysroot
zcat /root/sysroot.gz |cpio -id
sync同步,完成修复

第七步:让根文件系统能直接读写方式挂载
cd /mnt/sysroot
vim etc/fstab
/dev/hda2 / ext3 defaults 0 0
/dev/hda1 /boot ext3 defaults 0 0
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
保存退出
vim etc/rc.d/rc.sysinit添加
echo "Remount rootfs..."
mount -n -o remount,rw /
保存退出
mkdir etc/sysconfig
vim network
HOSTNAME=minilinux
保存退出
再编辑vim etc/rc.d/rc.sysinit添加
echo "Set the hostname..."
[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network
[ -z $HOSTNAME -o "$HOSTNAME" == '(none)' ] && HOSTNAME=localhost
/bin/hostname $HOSTNAME
保存退出
sync同步

第八步:在系统启动时设置一些启动成功或失败的提示信息
cat /etc/rc.d/init.d/functions 定义了一些函数,公共功能启动时表示出相应的提示信息
定义显示颜色
vim /mnt/sysroot/etc/rc.d/init.d/functions 此脚本在tserver脚本中装载函数调用

SCREEN=`stty -F /dev/console size 2> /dev/null`
COLUMNS=${SCREEN#* }
[ -z $COLUMNS ] && COLUMNS=80
SPA_COL=$[$COLUMNS-12]
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033[34m'
NORMAL='\033[0m'
success() {
string=$1
RT_SPA=$[$SPA_COL-${#string}]
echo -n "$string"
for I in seq 1 $RT_SPA; do
echo -n " "
done
echo -e "[ ${GREEN}OK${NORMAL} ]"
failure() {
string=$1
RT_SPA=$[$SPA_COL-${#string}]
echo -n "$string"
for I in seq 1 $RT_SPA; do
echo -n " "
done
echo -e "[ ${RED}FAILED${NORMAL} ]"
保存
脚本编程知识点:
变量中字符的长度:${$VARNAME}
A=“Startting tserver”
echo ${#A} A为变量名,在变量明前加#显示变量字符串长度个数,包括空格
使用stty -F /dev/console size 显示我们的物理终端设备显示的大小第一个数字为纵向的行,后面的数字为横向的列
stty -F /dev/console size | cut -d'' -f2
stty -F /dev/console size | awk '{print $2}'
A=`stty -F /dev/console size`
echo ${A#* } 表示从左往右第一个空格为分隔符的位置往左的字符显示出来
echo ${A##* } 表示从左往右最后一个空格为分隔符的位置往左的字符显示出来
echo ${A% *} 表示从右往左第一个空格为分隔符的位置往右的字符显示出来
echo ${A%% *} 表示从右往左最后一个空格为分隔符的位置往右的字符显示出来

第九步:正常系统启动服务的service常规操作
cd /mnt/sysroot
mkdir lib/modules
modinfo pcnet32 查看模块是否存在,并查看模块存放位置,并拷贝到新系统对应位置
cp /lib/modules/2.6.18-308.el5/kernel/deivers/net/pcnet32.ko /mnt/sysroot/lib/modules
cp /lib/modules/2.6.18-308.el5/kernel/deivers/net/mii.ko /mnt/sysroot/lib/modules
按需装载模块,启动网络服务时装载
vim etc/rc.d/rc.sysinit 添加以下内容
echo "Initializing network device..."
/sbin/insmod /lib/modules/mii.ko
/sbin/insmod /lib/modules/pcnet32.ko
保存退出
配置IP地址
mkdir -pv etc/sysconfig/network-scripts
vim etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
IPADDR=172.16.100.5
NETMASK=255.255.0.0
GATEWAY=172.16.0.1
ONBOOT=yes
保存退出

vim etc/rc.d/init.d/network
#!/bin/bash
#
#chkconfig:35 09 90
#descriprion:network service
prog=network
. /etc/rc.d/init.d/functions
CONF=/etc/sysconfig/network-scripts/ifcfg-eth0

. $CONF

start() {
ifconfig eth0 $IPADDR/$NETMASK up
[ -z $GATEWAY ] && route add default gw $GATEWAY
return 0
}

stop() {
ifconfig eth0 down
}

status() {
ifconfig eth0
}

usage() {
echo "$prog:{start|stop|restart|status}
}
case $1 in
start)
start
success "Config network eth0"
;;
stop)
stop
success "Stop network card eth0"
;;
restart)
stop
start
success "Restart network card eth0"
;;
status)
status
;;
*)
usage
exit 1
;;
esac
保存退出
chmod +x etc/rc.d/init.d/network
在不同级别下创建启动脚本链接文件
cd etc/rc.d/rc0.d
ln -sv ../init.d/network K90network
cd etc/rc.d/rc6.d
ln -sv ../init.d/network K90network
cd etc/rc.d/rc3.d
ln -sv ../init.d/network S09network
sync同步
切换mini系统即可使用service network start 启动网络

第十步:编辑用户登录之后登录信息之前的内容
终端提示信息:
/etc/issue内的内容而已
只需要提供此文件即可
cp /etc/issue /mnt/sysroot/etc/issue
并且编辑一下此文件,该为编辑系统的内容
vim /mnt/sysroot/etc/issue
MageEdu LINUX
Kernel \r on an \m

Mage Education Learning Services
http://www.magedu.com

第十一步:rc.sysinit:挂载额外文件系统/etc/fstab中定义其他文件系统
grep -E -v "\<swap|proc|sysfs\>" /etc/fstab | awk '{print $1}' | while read LINE; do awk '{print $1}' /proc/mounts | grep "`$LINE`" ; done
使用上面的命令过滤哪些设备还未挂载

vim /mnt/sysroot/etc/rc.d/rc.sysinit
在mount -a下添加:
[ $? -eq 0 ] && success "Mount others filesystem." || failure "Mount others filesystem."

第十二步:如何设定内核参数
/etc/sysctl.conf文件中行首的空白符;
sysctl -p
使用bincp.sh移植sysctl命令
vim etc/sysctl.conf脚本
#!/bin/bash
#
net.ipv4.ip_forward = 1
保存退出
在编辑vim /mnt/sysroot/etc/rc.d/rc.sysinit文件
添加
sysctl -p &> /dev/null
[ $? -eq 0] && success "Set kernel parameter" || failure "Set kernel parameter"
保存退出
sync同步

第十三步:如何支持用户账号登录
需要添加很多安全法则,比如密码规则等
PAM:pluggable Authentication Module
/etc/pam.d/* 都是跟PAM相关的
绕过PAM的方法
登录信息其实是有/bin/login程序来执行登录认证的,依赖于PAM,现在绕过此方法
重新编辑login程序,放置/bin目录下
用户登录:UID
组:GID
负责生成UID和GID的是
login:验证
/etc/passwd;/etc/shadow 系统默认为此
但可以放在NIS,LDAP,MYSQL等数据库中认证
nsswitch:Network Services Switch
框架:指定登录从哪里完成认证
如果想换登录认证方式就更改nsswitch即可
有一堆库文件:libnss_file.so(本地文件认证),libnss_nis.so(在nis中认证),libnss_ladp.so(到ladp中认证),需要什么认证方式就拷贝哪种库文件
再到配置文件:/etc/nsswitch.conf中指定库便可以选择哪种方式
定义了名称解析是如何工作的?主机名解析为ID,主机名解析为IP等等定义
库文件:
/lib/libnss* 的文件全部都是跟此nsswitch相关库,主要将files,compat相关的库文件复制新系统
/user/lib/libnss* 也有很多库,一般都链接到上面地址的库文件,只有libnssutil3.so,libnss3.so,libnssckbi.so三个文件是独立的,一般新系统拷贝这几个库文件即可

cp /lib/libnss_files* /mnt/sysroot/lib/ -d
cp /usr/lib/libnss_files* /mnt/sysroot/usr/lib/ -d
cp /usr/lib/libnss3.so /mnt/sysroot/usr/lib/ -d
cp /usr/lib/libnssckbi.so /mnt/sysroot/usr/lib/ -d
cp /usr/lib/libnssutil3.so /mnt/sysroot/usr/lib/ -d
sync
cp /etc/nsswitch /mnt/sysroot/etc/
vim /mnt/sysroot/etc/nsswitch.conf 做一些修改
hosts所属行,后面的内容全部删除即可
创建用户:
grep -E "^(root|hadoop)\>" /etc/passwd > /mnt/sysroot/etc/passwd
grep -E "^(root|hadoop)\>" /etc/shadow > /mnt/sysroot/etc/shadow
grep -E "^(root|hadoop)\>" /etc/group > /mnt/sysroot/etc/group
sync
bincp脚本添加passwd,userdel,usermod,groupadd等用户相关命令
此时可以将inittab中的agetty更改为mingetty的终端启动模式
编辑新的login脚本
ldd login查看是否有动态链接库
sync同步
切换新系统会提示用户登录信息
登录新系统后不是root的家目录,因为此时用户权限是不对的
因此需要编辑vim .pash_profile文件
PS1='[\u@\h \W]\$' #大写W为基名,小w为全名,会在前面显示整个路径
exprot PS1
保存退出

第十四步:添加单用户模式
chmod -R og=--- root/ 回收root目录权限
vim root/.bash_profile
exprot PS1='[\u@\h \W]\$'
vim etc/inittab
添加单用户级别模式
l1:1:wait:/etc/rc.d/rc 1
去掉与单用户无关的服务
cd etc/rc.d目录下
mkdir rc1.d
ln -sv ../init.d/network K90network
ln -sv ../init.d/tserver K33tserver
查看less /etc/init.d/single文件中如何定义
exec init -t1 S
拷贝single脚本直接用也可以
也可以自己编辑
vim etc/rc.d/init.d/single
#!/bin/bash
#
#chkconfig:
#descriprion:
#
case $1 in
start)
;;
*)
echo "Usage:single start"
;;
esac

exec init -t1 S 或 exec /sbin/init S
保存退出
chmod +x etc/rc.d/init.d/single
cd rc.d/rc1.d
ln -sv ../init.d/single S98single
sync同步

内核编译:
www.busybox.net
busybox
编译安装之后
/mnt/sysroot/bin下有个busybox的二进制文件
系统命令基本都链接到此程序

Kernel+ROOTFS()
Kernel+initrd(ramdisk)
busybox-->initrd

kernel+initrd(busybox)-->rootfs(busybox)

查看本机硬件设备信息:
1、cat /proc/cpuinfo
2、lsusb:列出本机的usb属性信息
3、lspci:列出本机的pci总线所有属性信息
4、hal-device:Hardware Abstract Layer,硬件抽象层
驱动的编译过程有两种:
1、直接做进内核;会使内核体积变大
2、做成模块进行加载;任意添加更便捷
两者需选择性编译,体积较小的可以做进内核,较大的编译为模块

编译内核:
1、配置
make menuconfig:以菜单形式进行模块选择,连续敲击空格键选择,选择完成后使用Esc退出,最后选择Yes保存并退出
make gconfig:Gnome桌面环境使用,需安装图形开发库:GNOME
make kconfig:KDE桌面环境,需安装图形开发库:KDE
make oldconfig
make config
最终都会保存.config文件
2、编译安装
make
make modules_install安装内核模块
make install

模块安装位置:/lib/modules/KERNEL_VERSION

如何实现部分编译:
1、只编译某子目录下的相关代码;
make dir/ 表示只编译此目录下的相关代码;如:make arch/ 表示跟硬件平台相关的内核核心,除了模块意外的所有内容;make drivers/只编译驱动
2、只编译部分模块:
make M=drivers/net/ 只编译网络驱动模块
3、只编译某一个模块
make M=drivers/net/pcnet32.ko
4、将编译完成的结果放置于别的目录中
make O=/tmp/kernel

5、交叉编译
make ARCH=

如何编译busybox:
下载Busybox源代码
tar xf busybox-1.20.2.tar.bz2
cd busybox-1.20.2
make menuconfig
进入菜单进行选择与编译内核一样
选择完需要使用的模块
进入busybox settings --->
再进入Build Options ---> 编译选项
选择Build BusyBox as a static binary(no shared libs)(NEW)静态的二进制程序
退出并进入Installation Options("make install" behavior) ---> 安装位置指定,可进行安装位置更改
yes保存退出
IDE:
/dev/hda1:ext3 /boot
/dev/hda2:ext3 /
编译好之后进行安装
make install 进行安装
安装相应busybox需要对应的内核版本来支持,否则会安装报错
找到新版本的内核包解压并进入对应目录
cd linux-2.6.38.5/include/mtd/
此目录下有个ubi-user.h的文件
mkdir /root/busybox-1.20.2/include/mtd 在源码包目录下创建mtd目录文件
将ubi-user.h文件复制到busybox源码目录下的mtd目录
cp linux-2.6.38.5/include/mtd/ubi-user.h /root/busybox-1.20.2/include/mtd/
cd busybox-1.20.2
在运行make install安装
安装完成后本目录下回出现一个_install目录将目录拷贝到相应目录
cp _install /tmp/busybox -a
cd /tmp/busybox
rm linuxrc 删除链接文件
1、建立rootfs
mkdir proc sys etc dev sysroot lib/modules sys
2、创建两个必要的设备文件:
mknod dve/console c 5 1
mknod dev/null c 3 1
modinfo ext3
可查到ext3依赖jbd
modinfo jbd
无依赖关系
cp /lib/modules/2.6.18-308.el5/kernel/fs/jbd/jbd.ko lib/modules/
cp /lib/modules/2.6.18-308.el5/kernel/fs/ext3/ext3.ko lib/modules/
3、为initrd制作init程序,此程序的主要任务是实现rootfs的切换,因此,可以以脚本的方式来实现它
编辑init脚本
#rm linuxrc
vim init
#!/bin/sh
#
mount -t proc proc /proc
mount -t sysfs sysfs /sys

insmod /lib/modules/jbd.ko
insmod /lib/modules/ext3.ko
mdev -s
mount -t ext3 /dev/hda2 /mnt/sysroot
exec switch_root /mnt/sysroot /sbin/init
保存退出
chmod +x init
4、制作initrd
mkdir tmp
find . |cpio -H newc -quiet -o |gzip -9 > /mnt/boot/initrd.gz
ls -lh /mnt/boot/initrd.gz
拷贝内核
cp /boot/vmlinuz-2.6.18-308.el5 /mnt/boot/vmliunz
grub-install --root-directory=/mnt /dev/hda
vim /mnt/boot/grub/grub.conf
default=0
timeout=3
title MageEdu Linux2(2.6.18)
root(hd0,0)
kernel /vmlinuz ro root=/dev/hda2
initrd /initrd.gz

保存退出
cd busybox-1.20.2
cp _install/* /mnt/sysroot/ -a
cd /mnt/sysroot/
rm linuxrc
mkdir proc sys dev tmp var/{log,lock,run} lib /etc/rc.d/init.d root boot mnt media
vim etc/inittab
::sysinit:/etc/rc.d/rc.sysinit
console::respawn:-/bin/sh
::ctrlaltfdel:/sbin/reboot
::shutdown:/bin/umount -a -r
保存退出

5、为系统准备一个“文件系统表”配置文件/etc/fstab
vim /etc/fstab
添加如下内容:
sysfs /sys sysfs default 0 0
proc /proc proc default 0 0
/dev/hda1 /boot ext3 default 0 0
/dev/hda2 / ext3 default 1 1
sync
mknod dev/console c 5 1
mknod dev/null c 1 3

6、创建系统初始化脚本文件
vim etc/rc.d/rc.sysinit
#!/bin/sh
echo -e Welcome to \033[34mMageEdu \033[0m Linux"
echo -e "Remounting the root filesystem ..........[ \033[32mOK\033[0m ]"
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -o remount,rw /

echo -e "Creating the files of device.............[ \033[32mOK\033[0m ]"
mdev -s
echo -e " Mounting the filesystem..................[ \033[32mOK\033[0m ]"
mount -a
swapon -a
echo -e "Starting the log daemon ..................[ \033[32mOK\033[0m ]"
syslogd
klogd
echo -e "Configuring loopback initerface ...........[ \033[32mOK\033[0m ]
ifconfig lo 127.0.0.1/24
ifconfig eth0 172.16.100.9/16
保存退出
chmod +x etc/rc.d/rc.sysinit
sync

cross compile:交叉编译

在x86、32bit、ARM等不同系统中想让系统在另一个平台运行,就需要交叉编译,需要用目标平台的内核进行编译

脚本编程知识点:
1、变量中字符的长度:$(#VARNAME)
2、变量赋值等:
${parameter:-word}:如果parameter为空或未定义,则变量展开为”word“;否则,展开为parameter值
${parameter:+word}:如果parameter为空或未定义,不做任何操作;否则,展开为parameter值
${parameter:=word}:如果parameter为空或未定义,则变量展开为”word“;并将展开后的值赋值给parameter
${parameter:offset}
${parameter:offset:length}:取子串,从offset处的后一个字符开始,取lenth长的子串;

脚本赋值:
赋值案例:
A=3:赋值A的变量为3
echo ${A:-30}:如果A有值则显示自己之前定义值,如果没有值则定义为30
unset A:将A的变量撤销回收
再次执行echo ${A:-30}时,赋值则变为了30,此时echo $A的值为空
A=${A:-30}:此时A的值为30,如果A有值则用自己,如果没有将A的值定义为30

echo ${A:+30}:结果为空则最终值为空,如果A不空则使用后面的30
echo ${A:=30}:如果A为空,不但展开字符串为30,则A的变量也定义为30,因此echo $A结果也是30

变量字符截取案例:
A='hello world'
echo ${A:2:3}:取出结果为llo,2表示从字符串开头开始略过几个字符,3表示往后截取几个字符;3字符可省略,结果就是略过2个字符后面所有的字符;

3、脚本配置文件
/etc/rc.d/init.d/服务脚本
服务脚本支持配置文件:/etc/sysconfig/服务脚本同名的配置文件

例如:写一个脚本,脚本作用只要变量不为空就显示出来
vim a.sh
#!/bin/bash
#

[ -n "$TEST" ] && echo $TEST
保存退出
再编辑一个配置文件
vim a.conf
TEST='hello world'
保存退出
如果要让脚本顺利如初配置文件的内容则在脚本中添加
. /root/a.conf
如果配置文件也没有赋值则使用
TEST=${TEST:-info}

4、局部变量:local VAR_NAME=

a=1
test() {
a=${3+4}
}

test
for I in `seq $a 10`; do
echo $I
done

局部变量前加local,就不是全局变量了,同样是这个脚本
test() {
local a=${3+4}
}
在函数中加了local那么这个a就不会引用前面a=1的变量了,所以如果变量只在某个函数中生效那就在变量前加local

5、命令mktemp:创建临时文件或目录
mktemp /tmp/file.XX
同样一个file文件可以多次创建,使用mktemp命令会生成不同版本的file.93,file.94依次创建不同版本
还可以同样mktemp /tmp/file.XXXX 都会生成不同字符串来区分不同的文件
变量引用:
FILE=·mktemp /tmp/file.XXXXX
echo $FILE 就会输出最近一次生成的临时文件,如果删除就直接rm $FILE即可
mktemp -d /tmp/file.XX 生成临时目录
tmp目录每隔30天未被访问过的文件或目录就会被清理掉

6、信号:进程间相互传递的信息
kill -l:查看所有信号的ID号
kill -SIGNAL PID
1:HUP
2:INT
9:KILL
15:TERM

脚本中,能实现信号捕捉,但9和15无法捕捉
Ctrl+c:SIGINT
trap命令:实现信号捕捉
trap 'COMMAND' 信号列表
脚本示例:
vim showdate.sh
#!/bin/bash
#
trap 'echo "You go..." INT #捕捉信息是Ctrl+c无法终止
while :; do
date
sleep 2
done
保存退出
Ctrl+z:SIGCONT 后台执行,在无法执行Ctrl+c的时候可以用此命令送至后台执行
然后执行kill %1将后台进任务杀死即可

vim ping.sh
#!/bin/bash
#
NET=192.168.0
for I in {200..254}; do
if ping -c 1 -W 1 $NET.$I &> /dev/null; then
echo "$NET.$I is up."
else
echo "$NET.$I is down."
fi
done
此脚本执行时无法执行Ctrl+c终止,因为ping命令捕捉了Ctrl+c信号,ping命令不进行了而已,但是bash脚本并没有接收到终止信号
除非在脚本中添加捕捉脚本的信息:
trap 'echo "quit.";exit 1' INT

如果想在脚本执行时出现的一些变量或临时文件在脚本执行结束后清理掉添加:
clearup() {
echo "quit..."
exit 1
}
trap 'clearup' INT 添加此信号捕捉可以将函数中的项清理掉

7、一行执行多个语句,语句间用分号隔开即可
如:trap 'echo "quit.";exit 1' INT
输出了quit.并且执行了exit 1退出命令

任务计划:
1、在未来的某个时间点执行一次某个任务;
/etc/at.deny和/etc/at.allow文件可以拒绝或允许某些用户不能执行at命令,两个文件都有的用户只有allow生效,两个都不存在的情况下只有root可以使用,文件为空表示任何人都允许或不允许
at 时间 执行执行时间
at> Command:要执行的内容
at>Ctrl+d 提交
指定时间:
绝对时间:
HH:MM,DD.MM.YY MM/DD/YY 如:10:20:指定某个时间点
相对时间:now+#(minutes,hours,days,weeks)
单位:minutes,hours,days,weeks
now+3minutes:从现在开始往后3分钟
MM/DD/YY 或 DD.MM.YY:某月/某日/某年 或者 某日.某月.某年
模糊时间:
noon,midnight,teatime
命令的执行结果:将以邮件的行事发送给安排任务的用户。
at -l:查看当前所有作业列表信息
at -d 作业号:删除某个作业

batch:自动选择系统较空闲的时刻运行任务,因此不需要指定时间

2、周期性的执行某任务;
cron:自身是一个不间断运行的服务
1、系统cron
/etc/crontab:每个段之间用空格隔开
格式:分钟 小时 天 月 周 用户 任务
2、用户cron
/var/spool/cron/USERNAME
格式:分钟 小时 天 月 周 任务
时间的有效取值范围:
分钟:0-59
小时:0-23
天:1-31
月:1-12
周:0-7,0和7都表示周日
时间通配表示:
*:对应时间的所有有效取值
3 * * * *:表示每个小时的第3分执行一次
3 * * * 7:每个周日每个小时的第3分钟
13 12 * * *:每天12点13分执行一次
13 12 6 * 3:每个月6号并且是星期3的12点13分执行一次,几率很低
13 12 6 7 *:每年7月6号的12点13分执行
,:离散时间点:
10,40 * * * 2,5:每周2和周5的每小时的第10分和第40分执行一次
-:连续时间点
10 02 * * 1-5:每周1到周5的2点10分都执行一次
/#:对应取值范围内每多久执行一次
*/3 * * * *:每3分钟执行一次

用户任务的管理:
crontab:
-l:列出当前用户的所有cron任务
-e:以vi形式进行编辑任务和执行时间
-r:移除所有任务
-u USERNAME -e:管理其他用户的cron任务

执行结果将以邮件形式发送给管理员:
*/3 * * * * /bin/cat /etc/fstab > /dev/null :即可避免每次发送邮件,但保留错误信息,如果都不显示&> /dev/null即可
cron的环境变量:cron执行所有命令都去PATH环境变量指定路径下去照
PATH:/bin:/sbin:/usr/bin:/usr/sbin
调用脚本时先定义PATH环境变量
#!/bin/bash
exprot PATH=/bin:/sbin:/usr/bin:/usr/sbin
cron系统任务执行为目录,在某个时间点将目录下脚本全部执行一次,按字母顺序排位陆续执行如果想提前或者用靠前的字母或者使用数字00,01来进行排序执行

anacron:cron的补充,能够实现让cron因为各种原因在过去的时间点该执行而未执行的任务在恢复正常后执行一次
/etc/anacrontab
文件内第一列数字表示有#天未执行了,第二列数字表示开机后的第##分钟开始运行,

确保service crond status是运行的
service anacron status 如果用到anacron也可以开启此服务,但服务器一般不会关机因此基本用不到

chkconfig --list crond 可以查看是否开机运行

Linux内核及编译

linux系统安装和kickstart

故障排除

Kernel + initrd (busybox制作,提供ext3文件系统模块) + ROOTFS(busybox制作)

make arch/ 只编译对应目录下的所有源程序,但依旧会遍历各模块
arch/x86/boot/bzImage 表示以bz方式压缩之后的内核镜像文件,拷贝到/boot下更名为linuzimage

硬件驱动:
initrd:仅需要提供内核访问真正的根文件系统所在设备需要的驱动
存储设备和文件系统相关的模块
rc.sysinit:系统初始化脚本
初始其他硬件的驱动程序

ROOTFS:busybox,init不支持运行级别
/etc/inittab:格式也不相同
默认支持:ash,hush
需要移至bash

内核编译:
先准备内核文件linux-2.6.38.5.tar.bz2
解压后ln linux-2.6.38.5 linux 链接到同目录下的linux目录
cd linux
开始编译模块制作.config文件
也可以下载自己制作号的文件,kernel-2.6.38.1-i686.cfg
mv kernel-2.6.38.1-i686.cfg .config 更名为.config就在内核源码包目录下
以此文件作为基础模板进行修改
make menuconfig
在Local version一项更改一下我们的版本名称
如果需要支持iscsi的话fusion MPT device support 如果在vmware环境下使用必须添加此模块,还有SCSI low-level drivers
备份.config文件
cp .config /root/config-2.6.38.5-i686.cfg
make drivers/net/pcnet32.ko 只编译网络模块
modinfo drivers/net/pcnet32.ko 查看依赖关系
无依赖模块即可
make arch/x86/ 或者 make SUBDIR=arch/ 只编译核心,不指定x86的话会根据当前系统的平台版本进行选择,有时会报错

1、安装grub
grub-install --root-directory=/mnt /dev/hda
检查/mnt/boot下有grub目录即可
2、拷贝内核
cp /boot/vmlinuz-2.6.18-308.el5 /mnt/boot/vmlinuz
sync
3、下载busybox
下载最新版的busybox
tar xf busybox-1.20.2.tar.bz2
mkdir busybox-1.20.2/include/mtd
因当前系统内核版本过低最新的busybox需要拷贝新内核的ubi-user.h文件到busybox源码包内
cp /usr/src/linux-2.6.38.5/include/mtd/ubi-user.h /busybox-1.20.2/include/mtd/
make menuconfig 按需选择所需功能
make install
此时出现编译未完成的情况,需要重新编译
make clean:清理之前编译好的二进制模块
make mrproper:清理之前编译所残留的任何操作,包括
cp /root/config-2.6.38.5-i686.cfg .config
make SUBDIR=arch/
mkdir /tmp/initrd
cp _install/* /tmp/initrd/ -a
cd /tmp/initrd
mkdir proc sys mnt/sysroot dev tmp lib/modules etc -pv
rm linuxrc
mknod dev/console c 5 1
mknod dev/null c 1 3
ls dev/ -l 可以看到console和null文件
编辑init脚本文件:
vim init
#!/bin/sh
#
mount -t proc proc /proc
mount -t sysfs sysfs /sys
insmod /lib/modules/jbd.ko
insmod /lib/modules/ext3.ko
mdev -s #通过sys目录输出所有硬件信息给用户空间
mount -t ext3 /dev/hda2 /mnt/sysroot
exec switch_root /mnt/sysroot /sbin/init #切换根文件系统,表示把根切换到/mnt/sysroot,并且执行/sbin/init
chmod +x init
find . |cpio -H newc --quiet -o |gzip -9 > /mnt/boot/initrd.gz
ll -h /mnt/boot 查看备份
modinfo jbd
modinfo ext3
cp /lib/modules/2.6.18-308.el5/kernel/fs/jbd/jbd.ko lib/modules/
cp /lib/modules/2.6.18-308.el5/kernel/fs/ext3/ext3.ko lib/modules/
find . |cpio -H newc --quiet -o |gzip -9 > /mnt/boot/initrd.gz
编辑grub.conf配置文件
vim /mnt/boot/grub/grub.conf
default=0
timeout=3
title MageEdu Tiny Linux(2.6.18)
root(hd0,0)
kernel /vmlinuz ro root=/dev/hda2
initrd /initrd.gz
保存退出
cp busybox-1.20.2/_install/* /mnt/sysroot/ -a
rm linuxrc
mkdir boot root etc/rc.d/init.d var/{log,lock,run} proc sys dev lib/modules tmp home mnt meida -pv
mknod dev/console c 5 1
mknod dev/null c 1 3
编辑inittab文件
vim etc/inittab
::sysinit:/etc/rc.d/rc.sysinit
console::respawn:-/bin/sh
::ctrlaltfdel:/sbin/reboot
::shutdown:/bin/umount -a -r
保存退出
编辑sysinit脚本
vim etc/rc.d/rc.sysinit
#!/bin/sh
echo -e Welcome to \033[34mMageEdu \033[0m Linux"
echo -e "Remounting the root filesystem ..........[ \033[32mOK\033[0m ]"
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -o remount,rw /
echo -e "Creating the files of device.............[ \033[32mOK\033[0m ]"
mdev -s
echo -e " Mounting the other filesystem..................[ \033[32mOK\033[0m ]"
mount -a
swapon -a
echo -e "Starting the log daemon ..................[ \033[32mOK\033[0m ]"
syslogd
klogd
echo -e "Configuring loopback initerface ...........[ \033[32mOK\033[0m ]
ifconfig lo 127.0.0.1/24
ifconfig eth0 172.16.100.9/16
保存退出
chmod +x etc/rc.d/rc.sysinit
sync
编辑fstab文件
vim /etc/fstab
添加如下内容:
sysfs /sys sysfs default 0 0
proc /proc proc default 0 0
/dev/hda1 /boot ext3 default 0 0
/dev/hda2 / ext3 default 1 1
sync
此时即可启动新的操作系统了
启用bash
使用bincp.sh脚本执行加载bash命令即可
chroot /mnt/sysroot 切换即可验证
cd /mnt/sysroot/bin/目录下有个sh链接文件当前链接到busybox我们需要重新链接他到bash即可
或者编辑配置文件
vim etc/inittab
更改console::respawn:-/bin/sh
改为console::respawn:-/bin/bash即可
实现用户登录:
grep -E "^root:" /etc/passwd > /mnt/sysroot/etc/passwd
grep -E "^root:" /etc/shadow > /mnt/sysroot/etc/shadow
grep -E "^root:" /etc/group > /mnt/sysroot/etc/group
ls /mnt/sysroot/etc检查三个文件是否已存在
查看passwd是否是bash启动
sync
vim etc/inittab
去掉console::respawn:-/bin/bash这一行
添加两行:
::respawn:/sbin/getty 9600 tty1 #9600是传输速率
::respawn:/sbin/getty 9600 tty2
保存退出
sync同步
添加主机名:
vim /mnt/sysroot/etc/hostname
HOSTNAME=tiny.magedu.com
vim /mnt/sysroot/etc/rc.d/rc.sysinit
添加:
echo "Set the hostname"
[ -f /etc/hostname ] && . /etc/hostname
[ -z "$HOSTNAME" -o "$HOSTNAME" == '(none)' ] HOSTNAME=localhost
hostname $HOSTNAME
提供登录前信息:
cp /etc/issue /mnt/sysroot/etc/issue
sync同步
为避免文件系统出错,首先备份配置
find .|cpio -H newc --quiet -o |gaip -9 > /root/tiny.1.gz
恢复备份:
umount /mnt/sysroot
mke2fs -j /dev/hda2
mount /dev/hda2 /mnt/sysroot
cd /mnt/sysroot
zcat /root/tiny.1.gz | cpio -id
sync
装载网卡驱动配置网卡:
modinfo mii
modinfo pcnet32
cp /lib/modules/2.6.18-308.el5/kernel/deivers/net/pcnet32.ko /mnt/sysroot/lib/modules
cp /lib/modules/2.6.18-308.el5/kernel/deivers/net/mii.ko /mnt/sysroot/lib/modules
按需装载模块,启动网络服务时装载
vim etc/rc.d/rc.sysinit 添加以下内容
echo "Initializing network device..."
/sbin/insmod /lib/modules/mii.ko
/sbin/insmod /lib/modules/pcnet32.ko
保存退出
配置IP地址
mkdir -pv etc/sysconfig/network-scripts
vim etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
IPADDR=172.16.100.5
NETMASK=255.255.0.0
GATEWAY=172.16.0.1
ONBOOT=yes
保存退出

vim etc/rc.d/init.d/network
#!/bin/bash
#
#chkconfig:35 09 90
#descriprion:network service
prog=network
. /etc/rc.d/init.d/functions
CONF=/etc/sysconfig/network-scripts/ifcfg-eth0

. $CONF

start() {
ifconfig eth0 $IPADDR/$NETMASK up
[ -z $GATEWAY ] && route add default gw $GATEWAY
return 0
}

stop() {
ifconfig eth0 down
}

status() {
ifconfig eth0
}

usage() {
echo "$prog:{start|stop|restart|status}
}
case $1 in
start)
start
success "Config network eth0"
;;
stop)
stop
success "Stop network card eth0"
;;
restart)
stop
start
success "Restart network card eth0"
;;
status)
status
;;
*)
usage
exit 1
;;
esac
保存退出
chmod +x etc/rc.d/init.d/network
在不同级别下创建启动脚本链接文件
cd etc/rc.d/rc0.d
ln -sv ../init.d/network K90network
cd etc/rc.d/rc6.d
ln -sv ../init.d/network K90network
cd etc/rc.d/rc3.d
ln -sv ../init.d/network S09network
sync同步
切换mini系统即可使用service network start 启动网络
系统创建过程:
1、安装grub
2、提供内核
3、提供initrd
4、创建根文件系统

Linux上的日志系统:
RHEL5:syslog
RHEL6:syslog-ng:syslog升级版,分开源版和商业版

日志系统:syslog()

syslog服务:
syslogd:系统,非内核的其他日志
klogd:内核日志,专门负责记录内核产生的日志信息

kernel --> 物理终端(/dev/console)--> /var/log/dmesg
#dmesg命令查看内核日志文件
可以查看到启动init程序之前所产生的信息
#cat /var/log/dmesg 也可查看

日志需要滚动(日志切割):
messages是最新的日志内容,定期会将旧日志生成messages.1 messages.2等旧日志归档
/sbin/init
/var/log/messages:系统标准错误日志信息;各子系统的产生的信息,非内核产生的引导信息,

logrotate:日志切割命令
/etc/cron.daily/logrotate:此脚本是系统定义的计划任务定期对日志进行滚动切割,默认每周滚动一次,只保留4个文件
编辑/etc/logrotate.conf文件进行滚动策略定义

/var/log/maillog:邮件系统产生的日志信息;
/var/log/secure:安全相关日志信息;默认权限为600;

syslog:
syslogd
服务配置文件:/etc/syslog.conf
配置文件定义格式为:facility.priority action
facility:可以理解为日志的来源或者设备目前常用的facility有以下几种:
auth:# 认证相关的
authpriv # 权限,授权相关的
cron # 任务计划相关的
daemon # 守护进程相关的
kern # 内核相关的
lpr # 打印相关的
mail # 邮件相关的
mark # 标记相关的
news # 新闻相关的
security # 安全相关的,与auth类似
syslog # syslog自己的
user # 用户相关
uucp # unix to unix cp 相关的
local0 到 local7 # 用户自定义使用
* # *表示所有facility

priority(log level)日志的级别,一般有以下几种级别(从低到高),级别越低记录越详细
debug # 程序或系统的调试信息
info # 一般信息
notice # 不影响正常功能,需要注意的消息
waring/warn # 可能影响系统功能,需要提醒用户的重要事件
err/error # 错误信息
crit # 比较严重的
alert # 必须马上处理的
emerg/panic # 会导致系统不可用的
* # 表示所有的日志级别
none # 跟*相反,表示啥也没有

action(动作)日志记录的位置
系统上的绝对路径 # 普通文件 如:/var/log/xxx
| # 管道 通过管道送给其他的命令处理
终端 # 终端 如:/dev/console
@HOSTNAME # 远程主机 如:@10.0.0.1
用户ID # 系统用户 如:root
* # 登录到系统上的所有用户,一般emerg级别的日志是这样定义的

定义格式例子:
mail.info /var/log/mail.log # 表示将mail相关的,级别为info及info以上级别的信息记录到/var/log/mail.log文件中
auth.=info @10.0.0.1 # 表示将auth相关的,基本为info的信息记录到10.0.0.1主机上去,前提是10.0.0.1要能接收其他主机发来的日志信息
user.!=error # 表示记录user相关的,不包括error级别的信息
user.!error # 与user.error相反
*.info # 表示记录所有的日志信息的info级别
mail.* # 表示记录mail相关的所有级别的信息
*.* #
cron.info;mail.infor # 多个日志来源可以用“;”隔开
cron,mail.info # 与cron.info;mail.info 是一个意思
mail.*;mail.!=info # 表示记录mail相关的所有级别信息,但是不包括info级别的
了解这些可以查看syslog.conf配置文件里的内容定义了
配置文件更改后一般使用servcie syslog reload来进行配置加载,尽量不要用restart有可能影响日志记录
在 /etc/sysconfig/syslog文件中
SYSLOG_OPTIONS="-r -m 0" 在此项配置中添加-r选项并重启服务即可把此服务器当作日志文件服务器,可接受其他服务器的日志文件;
在新建的小系统中添加日志功能
在etc/rc.d/rc.sysinit中添加syslogd和klogd即可启用日志服务
并创建etc/syslog.conf配置文件
如果无法正常生产日志,请检查文件系统是否ext3
klogd


信息详细程度:日志级别

子系统:facility,设施;把每个程序理解为一个子系统,每个子系统都可以生成自己的日志

动作:记录日志的过程


telnet:远程登录,tcp应用层协议,23/tcp
C/S
S:telnet服务器
C:telnet客户端
发送机制为明文,因此安全不高

ssh:Secure Shell,应用层协议,22/tcp
通信过程及认证过程是加密的,主机认证,用户认证过程加密,数据传输过程加密
服务器端会发送主机秘钥:
非对称加密:公钥和私钥能够配对才能完成认证
Secret key 服务器端发送私钥
Public key 客户端存有公钥
对称加密:加密和解密使用同一个密码
密钥交换

ssh v1版,v2版
v1版已经不算安全,容易被中间人截取用户秘钥并伪装客户端向服务器端发送请求,返回时伪装成服务器返回给客户端
man-in-middle
v2版本相对安全

认证过程:
基于口令认证
基于秘钥认证

协议:规范
实现:服务器端、客户端

Linux:openSSH
C/S
服务器端:sshd,配置文件/etc/ssh/sshd_config
客户端:ssh,配置文件/etc/ssh/ssh_config
ssh:远程登录对端服务器
ssh-keygen:秘钥生成器
ssh-copy-id:将公钥传输至远程服务器
scp:跨主机安全复制工具

ssh:
ssh USERNAME@HOST
第一次登录会接受一个秘钥:存放位置默认在root用户的/root/.ssh/目录下known_hosts文件
ssh -l USERNAME HOST
ssh USERNAME@HOST ‘COMMAND’:这样在对端执行输入的命令后自动退出,不会登录到对端服务器

scp:
scp SRC DEST
-r:递归复制
-a:全部复制
例:
scp USERNAME@HOST:/path/to/somafile /path/to/local
scp /path/to/local USERNAME@HOST:/path/to/somafile

ssh-keygen:
-t rsa
秘钥保存在:~/.ssh/id_rsa
~/.ssh/id_rsa.pub 公钥复制到远程主机对应用户的家目录下的.ssh/authorized_keys文件或者.ssh/authorized_keys2文件中,不能覆盖要追加入此文件中
例:生成秘钥并与对端认证
ssh-keygen -t rsa回车,会通知你生成秘钥的位置,输入密码无需输入直接回车生成
-f /path/to/key_file:直接指定存放的秘钥名称和位置
-P '':指定加密私钥的密码
scp .shh/id_rsa.pub root@172.16.200.1:/root 复制到对端
登录对端主机:
mkdir .ssh
chmod 700 .ssh # .ssh目录的权限一定是700的
cat id_rsa.pub >> .ssh/authorized_keys
再次登录对端无需输入密码,完成基于秘钥的认证过程

删除创建的.ssh目录,在id_rsa.pub生成之后使用ssh-copy-id命令进行复制,会自动完成创建目录追加文件内容的动作
ssh-copy-id -i ~/.ssh/id_rsa.pub root@176.16.200.1 # 无需输入具体位置直接回车即可

向新创建的小系统移至ssh远程登录:
dropbear:嵌入式系统专用的ssh服务器端和客户端工具
服务器端:dropbear
dropbearkey:为服务器端实现主机认证
客户端:dbclient

1、dropbear默认使用nsswitch实现名称解析
/etc/nsswitch.conf
/lib/libnss_files*
/usr/lib/libnss3.so
/usr/lib/libnss_files*

2、dropbear会在用户登录检查其默认shell是否当前系统的安全shell
/etc/shells

3、必须挂载伪终端

具体创建步骤:
下载dropbear-2013.56.tar.bz2文件
tar xf dropbear-2013.56.tar.bz2
cd dropbear-201.56
.configure
make
make install
执行bincp.sh将dropbear、dropbearkey、dbclient命令移至过去
sync同步

添加支持的shell
cd /mnt/sysroot
vim etc/shells
/bin/sh
/bin/bash
/bin/ash
/bin/hush

vim etc/fstab 添加下面一行伪终端
devpts /dev/pts devpts mod=620 0 0
保存退出
mkdir dev/pts
sync同步

创建主机密钥默认位置:
etc/dropbear/
RSA:dropbear_rsa_host_key
长度可变,只要是8的整数倍,默认为1024
DSS:dropbear_dss_host_key
长度固定,默认1024
mkdir etc/dropbear
dropbearkey
-t rsa|dsa:指定秘钥类型
-f /path/to/KEY_FILE :指定位置和名称
-s SIZE :指定长度

dropbearkey -t rsa -f /mnt/sysroot/etc/dropbear/dropbear_rsa_host_key -s 2048 # 回车生成rsa秘钥
dropbearkey -t dss -f /mnt/sysroot/etc/dropbear/dropbear_dss_host_key # 回车生成dss秘钥,无需指定长度
ls etc/dropbear/ # 查看两个生成的秘钥文件是否存在/dropbear_rsa_host_key和dropbear_dss_host_key

复制NSS
mkdir usr/lib
cp -d /lib/libnss_files* /mnt/sysroot/lib/
cp -d /lib/libnss3.so /lib/libnss_file.so /mnt/sysroot/lib/
cp /etc/nsswitch.conf /mnt/sysroot/etc/
vim /mnt/sysroot/etc/nsswitch.conf
只保留4行即可
passwd: files
shadow: files
group: files
hosts: files dns
保存退出
sync同步

在小系统中启动dropbear
/usr/local/sbin/dropbear -E -F # 第一次启动可以使用-E和-F选项表示前端运行
然后用ssh客户端进行远程登录测试
确认服务没有问题后可以取消前台运行
/usr/local/sbin/dropbear # 直接执行后台运行此命令
使用dbclient命令远程登录其他服务器
如:
/usr/local/bin/dbclient -l root 172.16.200.1
输入密码即可远程登录

系统安装过程:利用kickstart工具完成自制自定义自动安装光盘;
anaconda:stage2.img
text,GUI
kickstart:三部分
/root/anaconda-ks.cfg:保存了安装过程中自定义安装的内容
命令段:
必备命令
keyboard
lang
timezone Asia/Shanghai
authconfig --useshadow
bootloader --location
clearpar
--initlabe :初始化分区表
--linux :清除系统中linux的分区信息
driverdisk --source=ftp://path/to/dd.img 或 http://path/to/dd.img
firewall --enabled|disabled:一般为禁用
firstboot --disabled:一般为禁用,安装结束后还要配置一些信息,关闭后无需配置
text|graphical:文本界面或图形界面安装,不选则为图形界面
key --skip :跳过提供秘钥
keyboard us:指定键盘类型为us
lang en_US 或 zh_CN:指定语言
#创建分区过程:
#clearpart --all --initlabel
#part /boot --fstype ext3 --size=100
#part pv.100000 --size=40960 #pv.100000数字可任意使用前面创建和后面分配一致即可,ID号
#part swap --size=1024
#volgroup vol0 --pesize=32768 pv.100000
#logvol / --fstype ext3 --name=root --vgname=vol0 --size=32000
#logvol /home --fstype ext3 --name=home --vgname=vol0 --size=1984
配置网络
network --bootproto=dhcp|static --ip=10.0.2.15 --netmask=255.255.255.0 --gateway=10.0.2.254 --nameserver=10.0.2.1,192.168.1.1
rootpw --iscrypted:加密设置root密码
selinux --disabled|permissive|enabled:一般为禁用,建议使用--permissive
skipx:跳过图形配置
upgrade:升级系统
#yum install system-config-kickstart
ksvalidator:检查ks中是否有语法错误
kevalidator /root/anaconda-ks.cfg #不报任何信息则为无语法错误
运行system-config-kickstart命令直接跳出图形界面进行配置,所有配置项都会有,可以打开某个配置文件为范本基础上更改,最后保存
用下面命令生成安装引导盘:
mkisofs -R -b isolinux/isolinux.bin -no-emul-boot -boot-load-size 4 -boot-info-table -o boot.iso iso/
生成后的boot.iso文件挂载到cdrom中设置cdrom启动,引导到boot界面直接回车,完成安装过程

可选命令
软件包选择段:%packages
脚本段:
%pre:预安装脚本段
%post:后安装脚本段

安装过程中,boot提示符中可以使用的命令:
askmehod
dd=:加载额外的驱动盘
ip=地址
netmask=子网掩码
gateway=网关
dns=DNS服务器地址
ks=指定哪里获取ks配置文件
ks=http://
ks=cdrom:/
ks=hd:<device>:/<file> 硬盘某个分区获取,例:ks=hd:sda3:/mydir/ks.cfg
ks=file:/<file> 表示在系统中initrd中获取配置信息
ksdevice=<device> 指定某个网卡设备,例:ksdevice=eth1 或 ks=nfs:<server>:/<path> ksdevice=eth1
noprobe:不装载硬件设备
rescue:进入紧急救援模式

常见的系统故障排除:
1、确定问题的故障特征
2、故障重现
3、使用工具收集进一步信息
4、排除不可能的原因
5、定位故障:
从简单的问题入手
一次尝试一种方式

故障排除规则:
1、备份原文件
2、尽可能借助于工具

可能会出现的故障:
1、管理员密码忘记
进入单用户模式,读写方式挂载根目录,运行passwd 直接更改root密码即可
2、系统无法正常启动
a、grub损坏(MBR损坏、grub配置文件丢失)
dd if=/dev/sda of=/root/mbr.backup count=1 bs=512 # 最好放置其他磁盘备份,备份mbr
dd if=/dev/zero of=/dev/sda count=1 bs=200 #清除mbr空间
sync同步
shutdown -r now 重启
修复方式:
1、借助别的主机修复;
2、使用紧急救援模式;
a、boot.iso
b、使用完整的系统安装光盘
boot:linux rescue # 进入救援模式,类似于WinPE,需要挂载真正的根文件系统
选择语言以及键盘输入类型,而后调用anaconda启动一个小型的linux系统
一般会将根挂载到/mnt/sysimage挂载
输入grub进入grub命令行模式
grub>find (hd0,0)/ # 挨个输入设备号进行查找,如果找到vmlinuz内核文件即可
grub>root (hd0,0) # 设定根
grub>setup (hd0) # 安装grub
quit退出grub
sync同步
reboot重启主机即可完成修复
grub配置文件丢失:
grub>find (hd0,0)/
grub>root (hd0,0)
grub>kernel /vmlinuz-对应内核版本号 后面的根指定不指定均可 ro root=/dev/vol0/root rhgb quiet
grub>initrd /initrd-xxx.img 对应内核版本号必须完全匹配
grub>boot
启动之后进入到grub目录下重建grub配置文件即可
grub.conf
default=0
timeout=10
title RHEL 5.8
root (hd0,0)
kernel /vmlinuz-2.6.18-308.el5 ro root=/dev/vol0/root quiet
initrd /initramfs-2.6.32-358.el6.x86_64.img #ramdisk文件路径

b、系统初始化故障(某文件系统无法正常挂载、驱动不兼容、kernel panic:内核恐慌)
1、无法正常挂载和驱动不兼容
grub:编辑模式,进入1级别单用户模式emergency
进入系统后修复相应的fstab或者修复驱动等配置脚本文件即可
2、默认级别设定为了0或6
grub:编辑模式,进入1级别单用户模式emergency
修改inittab启动级别修改为3或5即可
3、误删除/etc/rc.d/rc3.d目录不小心删除了
进入1级别单用户模式emergency
修复目录内脚本

c、服务故障
某服务故障导致启动停止,类似sendmail修复如下:
sendmail服务,系统时钟不准确时会导致配置文件时间戳检查无法通过启动系统时停留在sendmail服务处卡住
1、修复sendmail时间戳
2、单用户模式下,停止sendmail服务随系统启动
3、启动系统时,出现红色redhat字样时会提示按I键进入交互式模式,进入后选择卡住的服务停止启动
在rc.local文件中启动了关机或者重启命令也会对启动有影响
进入单用户,将相应启动级别目录下的rc.local中内容修改

d、用户无法登陆系统(mingetty,bash程序故障)
比如不小心将/bin/bash删除了,关机都无法执行了
修复过程:无法进入单用户模式
修复bash:
紧急救援模式:重装bash
bios里设置CDROM启动,使用系统光盘启动
boot:linux rescue 进入救援模式
挂载hdc设备既是光驱设备
mount /dev/hdc /media
cd /media
cd Server
ls |grep bash
rpm -ivh --replacepkgs --root /mnt/sysimage bash-3.2-32.el5.i386.rpm # --replacepkgs 替换安装,如果这样执行就安装到当前救援模式的小系统中了
因此我们需要添加--root /mnt/sysimage表示安装时以此目录为根进行安装
当然也可以直接使用chroot /mnt/sysimage切到本机系统中进行光驱挂载和bash安装也可以完成bash修复
修复完成切记使用sync进行同步
修复mingetty:
可以进入单用户模式后手动启动网络服务
再将相应的mingetty程序包拷贝过来进行安装修复

3、命令无法运行
环境变量被损坏
例如:本应添加环境变量时 export PATH=$PATH:/data/bin,但不小心写成export PATH=/data/bin,结果只能执行/data/bin下的命令了,任何命令都无法执行了
修复:
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:....将环境变量重新指定回来
或者最简单的,修改不是改的配置文件,把当前shell关闭,重新登录即可
或者使用全路径更改配置文件:
/usr/bin/vim /etc/profile 修改全局环境变量配置文件即可
最好选择一款版本控制软件进行备份关键配置文件
svn,git均是常用版本控制软件,可以恢复至之前的版本

4、编译过程无法继续(开发环境缺少基本组件)
将开发环境安装进去即可,主要观察编译命令最后报错信息来找到关键错误所在

50台服务器:
网络:定义网络属性,tom
用户:用户管理,jerry

Linux:root
Tom:root,

用户:管理员和普通用户

sudo COMMAND:某个用户能够以另外哪个用户的身份通过哪些主机执行某命令的机制

需要输入:jerry密码

sudo的配置文件:/etc/sudoers 默认为440权限

visudo:编辑sudoers命令,可检查语法错误

sudo以条目形式添加规则:
who which_hosts=(runas) command
谁 在哪些主机上以哪种身份 运行什么命令

别名:别名必须全部而且只能使用大写英文字母的组合 ALL为所有
用户别名:User_Alias,为who定义别名,可以定义多个用户
语法:User_Alias USERADMIN = %用户名 # 前面加!可以取反值
可包含系统用户的用户名
组名,使用%引导组名
还可以包含其它已经定义的用户别名
Host别名:Host_Alias,可以定义主机组
语法:Host_Alias HOSTADMIN = %主机名,IP # 前面加!可以取反值
主机名
IP地址
网络地址
其它主机别名
runas别名:Runas_Alias,定义多种身份别名
语法:Runas_Alias RUNASADMIN = 用户名,组名 # 前面加!可以取反值
用户名
%组名
其它的Runas别名
command别名:Cmnd_Alias,定义多个命令
语法:Cmnd_Alias CMNDADMIN = 命令路径,目录 # 前面加!可以取反值
命令路径
目录(此目录内的所有命令)
其它事先定义过的命令别名
在COMMAND前加TAG标签可以在执行命令前做一些其他动作例如:
NOPASSWD:/usr/sbin/useradd,/usr/sbin/usermod 这样写在sudo执行命令时就无需输入密码认证了
NOPASSWD:/usr/sbin/useradd, PASSWD: /usr/sbin/usermod 这样写是useradd无需密码,usermod还需要密码

别名设置示例:
visudo
User_Alias USERADMIN = hadoop,%hadoop,%useradmin
Cmnd_Alias USERADMINCMND = /usr/sbin/useradd,/usr/sbin/usermod,/usr/sbin/userdel,/user/bin/passwd [A-Za-z]*,! /user/bin/passwd root # !后面是排除掉不允许执行的root密码更改的命令,取反优先级更高
USERADMIN ALL=(root) NOPASSWD:USERADMINCMND

使用示例:hadoop以管理员身份执行useradd和usermod命令
useradd hadoop
su hadoop
sudo /usr/sbin/useradd tom
输入密码
提示sudoers文件中没有hadoop信息
visudo
在最后新增一行
hadoop ALL=(root) /usr/sbin/useradd,/usr/sbin/usermod
保存退出
再次执行
sudo /usr/sbin/useradd tom

sudo第一次输入密码后,5分钟之内是无需再次输入密码的
sudo -k:让认证信息失效,并重新认证
sudo -l:列出当前用户所有可以使用的所有sudo命令

sudo执行的任何操作都会记录在/var/log/secure日志中

TCP/IP:安全
机密性:明文传输(ftp,http,smtp,telnet)
加密:plaintext明文 --> 转换规则 --> ciphertext密文
解密:ciphertext密文 --> 转换规则 --> plaintext明文
转换算法:密钥
对称加密:算法结合密钥进行加密解密,密钥是相同的

对称加密算法:
DES:Data Encrption Standard,56bit加密秘钥
3DES:将数据3次DES加密,常用
AES:Advanced Encrption Standard, 128bit加密秘钥,常用
AES192,AES256,AES512,可定义秘钥长度,越长安全性越高,但耗时越多
Blowfish:常见的对称加密算法
单向加密算法:
MD4
MD5
SHA1
SHA192,SHA256,SHA384这里指输出长度
CRC-32:循环冗余校验码

公钥加密:核心功能(加密、签名)
身份认证
数据加密
秘钥交换
RSA:dropbear_rsa_host_key 加密、签名
DSA:只能实现签名,公开使用软件,美国国家安全局
ElGamal:商业算法,需要付费使用

数据完整性:数据篡改
单向加密算法:提取数据特征码
1、输入相同;输出必然相同
2、雪崩效应:输入的微小改变,将会引起结果的巨大改变
3、定长输出:无论原始数据是多大,结果大小都是相同的
4、不可逆:无法根据特征码还原原来的数据
协商生成密码:密钥交换(Internet Key Exchange,IKE)
需要Diffie-Hellman协议完成互联网交换算法
P,G(大素数,生成数)
传输方和接收方各选择一个随机数x和y
A:将g^x%p --> B
B:将g^y%p --> A
A:(g^y%p)^x=g^yx%p
B:(g^x%p)^y=g^xy%p
身份验证:
公钥加密算法:非对称加密算法
秘钥对:
公钥:p
私钥:s
发送方用自己的私钥加密数据,可以实现身份验证
发送方用对方的公钥加密数据,可以保证数据机密性

公钥加密算法很少用来加密数据:速度太慢

PKI:Public Key Infrastructure
CA:Certificate Authority
证书格式:
x509:主流格式
公钥及其有效期限
证书的合法拥有者
证书该如何被使用
CA的信息
CA签名的校验码
pkcs12

PKI:
TLS/SSL:x509格式证书
SSL:Secure Scoket Layer 安全套接字层,目前使用版本为v2和v3

TLS:Transport Layer Security 传输层安全

OpenGPG:另一种PKI加密格式,格式相似

https(tcp):
客户端发起连接请求
双方互相协商建立SSL会话,协商使用SSL还是TLS协议以及使用的版本号
协商好后server端会将自己的公钥证书发给客户端,客户端验证证书是否安全机构颁发,并且验证完整性
客户端建立一个会话秘钥,并且通过server端公钥将生成的会话秘钥一并加密后传递给server端
server端使用此客户端密码便可以加密数据发送给客户端了

私钥丢失:通过CRL:证书吊销列表。仍未过期因为其他原因而提前失效的证书信息
收到信息的一方会先从CRL中查看是否有此证书,如果有则失效

加密工具:
OpenSSL:SSL的开源实现,功能强大,涵盖世面所有加密格式
libcrypto:通用加密库,提供各种加密函数
libsshl:TLS/SSL的实现
基于会话的、实现了身份认证、数据机密性和会话完整性的TLS/SSL库
openssl:多用途命令行工具
实现私有证书办法机构
子命令:
openssl ? :可以给出标准子命令选项
speed:测试每种加密算法的性能评估,可跟加密算法,不加默认显示所有加密速率
enc -ciphername加密算法 -in filename从哪个文件读入 -out filename
加密后输出到哪个文件:
-e:加密
-d:解密
-k:指定加密秘钥
-salt:实现更高的安全性
例:加密:openssl enc -des3 -salt -a -in inittab -out inittab.des3
输入密码后生成加密文件
读取:openssl enc -des3 -d -salt -a -in inittab.des3 -out inittab
输入密码解密看原文件
passwd:给用户生成密码串
-1:指定使用MD5方式加密,输入正常的密码最后得出加密后的密码串
-1 -salt 输入指定的salt内容,得出内容一致,salt和passwd一样的情况下得出结果相同,salt内容在加密密码串的第二个$和第三个$中间的内容
rsa:加密、签名
rsautl
dsa:签名
rand:生成伪随机数,获得随机数openssl rand -base64 指定任意随机数长度位数,得出加密后的内容

查看文件特征码:
md5sum inittab:查看inittab的MD5校验码
sha1sum inittab:查看sha1校验码,长度不同
openssl dgst -sha1 inittab:查看sha1校验码,与上面的sha1校验码一致

注解:如果碰到与系统命令冲突的选项,先使用whatis passwd查看,找对应的选项来man,例如:man sslpasswd

rpm -ql openssl 可以查看与openssl包相关的所有文件

openssl实现私有CA:
1、先生成一对秘钥
openssl
genrsa 指定秘钥长度:生成一个rsa私钥,权限应是600,输出重定向为server.key保存为文件
-out 输出名称:也可以保存成文件
小窍门:
在输出命令时用()括起来,表示括号中的内容在子shell中执行,并且执行结束后自动退出子shell
例如:
(umask 077; openssl genrsa server1024.key 1024) # 直接执行命令并设置权限为600
再使用umask查看当前shell仍然是0022,不影响当前shell环境
提取公钥
openssl rsa -in server1024.key私钥文件 -pubout # 这样就输出了对应此私钥的公钥

2、生成自签署证书
openssl
req:生成证书工具
例:openssl req -new -x509 -key server1024.key -out server.crt -days 365
输入证书拥有者的信息:
国家代码:中国CN
省份名称:HeBei
城市名称:ShiJiaZhuang
单位名称:NanTian
部门名称:Tech
主机名称:与hostname保持一致(重要)
邮箱地址:donray_h@163.com
证书生成
cat server.crt 可以直接查看证书内容,但是密文
openssl x509 -text -in server.crt 以文本格式输出信息

使用秘钥证书:
cd /etc/pki/tls/
vim openssl.cnf
[ CA_default ]
下面的内容按照证书内容更改,最好写为绝对路径
[ req_distinguished_name ]
更改默认内容,上面生成证书过程的内容都可以默认为自己随填写的内容

为CA准备私钥和证书:
cd /etc/pki/CA
(umask 077,openssl genrsa -out private/cakey.pem 2048)
req -new -x509 -key private/cakey.pem -out cacert.pem
一直回车生成自签署证书
在CA目录下创建所需目录
mkdir certs newcerts crl
touch index.txt
touch serial
echo 01 > serial
此时CA服务器已创建完成
在另一台服务器使用这个CA服务器提供秘钥服务
登录另一台web服务器
cd /etc/httpd
mkdir ssl
cd ssl
(umask 077; openssl genrsa -out httpd.key 1024) 生成自己的私钥
生成证书颁发请求:
openssl req -new -key httpd.key -out httpd.csr # csr为证书签署请求
输入请求内容,必须与CA一致,更改则无法签署
最后可输入密码加密证书,直接敲回车则为不加密
远程发送请求给CA服务器
openssl ca -in httpd.csr -out httpd.crt -days 365
第一次y为是否签署
第二次为是否提交
当前目录就生成了httpd.crt
完成后再证书服务器中CA目录下查看index.txt文件可以看到相关注册信息
再 cat serial 也有相关信息即可

另外工具:
cd /etc/pki/tls/certs/
使用Makefile快速生成秘钥证书,只能在测试环境中使用,不能用在生产环境
在此目录直接执行make httpd.pem
生成私钥填写相关证书信息即可完成
将httpd.pem拷贝走即可,但此文件中既有私钥又有证书,也可以make xx.crt xx.csr等任何后缀的秘钥文件,可以查看makefile内容具体使用

OpenSSH:
开源版本的SSH工具
ssh:Secure SHell,TCP/22
C/S架构
v1,v2版本,v1已基本废弃

客户端:
Linux:ssh
Windows:putty,SecureCRT(商业版),SSHSecureShellClient,Xmanager(商业版)

服务器端:
sshd

openssh(ssh,sshd)
sshd:主机秘钥(第一次连接时发送)
1、客户端先同意接收服务器端的公钥
2、生成会话对称秘钥,用此秘钥加密数据发送即可

netstat
-r:查看路由
-n:以数字方式显示各主机或端口等相关信息
-l:listening监听状态
-t:代表TCP连接
-u:代表UDP连接
-p:process 进程

配置文件:
/etc/ssh/目录下
ssh客户端配置文件(ssh_config)
每次使用ssh命令登录另一台主机后,在主机目录下会创建.ssh目录,目录下会有known_host文件,里面会有主机IP地址和对应公钥信息,因此第二次再登录就无需再认证了
ssh -l USERNAME REMOTE_HOST ['command'] # 不登录对方主机,只显示对端主机执行命令的结果
-X:登录到对端并执行X11图形窗口命令
-Y:Y是开启X11并转换图形界面,因此Y比X更安全可靠
-p 端口号:指定端口号连接

sshd服务器端配置文件(sshd_config)
配置文件中,井号开头的全为注释,井号后面有空格的为纯注释行,没有空格的为可以启用的参数选项
Protocol 2 # ssh版本为v2版
Port 22 # 端口号,可以自定义为其他端口号
AddressFamily any # 支持IPv4 还是IPv6,any指都支持
ListenAddress 0.0.0.0 # 表示监听在哪个地址上,如果服务器多个地址,指定一个IP地址为对外提供sshd服务的地址,其他地址不对外提供此服务
HostKey for protocol version 1或2 # 为v1或v2版本指定key的私钥文件
KeyRegenerationInterval 1h # 秘钥多久更换一次,1h表示1小时
ServerKeyBits 768 # 此项表示服务器端秘钥长度为768位
SyslogFacility AUTHPRIV # 使用哪个Facility来记录日志
LogLevel INFO # 日志级别
LoginGraceTime 2m # 登录宽限期,表示输入用户名和输入密码之间的时长,超过多少就还原为初始状态
PermitRootLongin yes|no # 是否允许root用户直接登录
StrictModes yes|no # 是否使用严格限定模式
MaxAuthTries 6 # 超过多少次错误,锁定终端,禁止登录
PubkeyAuthentication yes|no # 基于秘钥的认证机制
AuthorizedKeysFile .ssh/authorized_keys # 客户端会生成秘钥并发送给服务器端的用户的家目录下指定文件位置和名称
PasswordAuthentication yes|no # 是否支持基于口令的认证
UsePAM yes|no # 是否使用PAM进行认证
X11Forwarding yes|no # 是否转发X11请求
Banner /some/path # 登录信息提示存储文件
PrintMotd yes|no # 是否显示MOTD文件内容/etc/motd
PrintLastLog yes|no # 是否显示上一次通过那个主机登录过,不应显示
Subsystem sftp /usr/libexec/openssh/sftp-server # ssh子系统sftp,可以基于ssh服务使用sftp

想更深入了解sshd_config文件内容,可以使用man sshd_config命令查看详细情况
AllowUsers # 允许哪些用户访问,白名单
DenyUsers # 拒绝哪些用户访问,黑名单
AllowGroup # 允许哪些组成员访问,白名单组
DenyGroup # 拒绝哪些组成员访问,黑名单组
黑白名单同时存在时,黑名单失效

目录下还有文件:
以下两套私钥和公钥是为v2版本算法使用的
ssh_host_dsa_key
ssh_host_dsa_key.pub
ssh_host_rsa_key
ssh_host_rsa_key.pub
以下私钥公钥是为v1算法使用的
ssh_host_key
ssh_host_key.pub
私钥文件是600权限

基于秘钥的认证:
一台主机位客户端(基于某个用户实现):
1、生成一对秘钥
ssh-keygen -t rsa # 回车后在用户家目录下.ssh/id_rsa,公钥就是id_rsa.pub
-t {rsa|dsa}:指定加密算法
-f /path/to/keyfile:自定义保存到哪个文件
.ssh目录为700权限,如果自己创建记得改目录权限,不改则无法使用
-N 'password':指定密码,也可以什么不写密码为空

2、将公钥传输至服务器端某用户的家目录下的.ssh/authorized_keys文件中
使用文件传输工具传输(ssh-copy-id,scp)
ssh-copy-id
-i /path/to/pubkey USERNAME@REMOTE_HOST
另一种方式:
scp -a /path/to/pubkey USERNAME@REMOTE_HOST:/home/hadoop/.ssh/pubkey
cat .ssh/pubkey >> .ssh/authorized_keys
3、测试登录

scp:基于ssh的远程复制命令,可以实现在主机之间传输数据
scp [options] SRC DEST
-r:复制目录
-a:递归复制
-p:保存原来权限信息,-a=-rp

sftp:基于ssh方式加密传输数据的命令
sftp root@172.16.100.2
get file # 下载某个文件
mget files # 下载多个文件
put file # 上传某个文件
mput files # 上传多个文件

总结:
1、密码应该经常换且足够复杂;
2、使用非正常端口;
3、限制登录客户端地址;
4、禁止管理员直接登录;
5、仅允许有限制用户登录;
6、使用基于秘钥的认证;
7、不要使用协议版本1;

远程免密登录:
在远程登录客户端生成本机的密钥
传到linux服务器上
cat id_rsa_1024.pub >> .ssh/authorized_keys
即可完成免密登录
登录时输入用户名后选择pubkey选项进行登录即可
使用其他端口号
ssh IP地址 端口号 #即可登录

嵌入式系统专用的ssh软件:dropbear 移至入自制操作系统,也可以实现远程连接

DNS:域名解析,BIND:Berkeley Internet Name Domain
SSL/TLS:http --> https --> OpenSSL,CA,Digital Certificate,PKI
HTTP:HTTP协议,Apache,LAMP,Nginx(Engine X),LNMP(LEMP),MySQL,PHP,varnish
CDN:DNS(View)智能DNS,varnish
File Server:NFS、SMB/CIFS、FTP
Netfilter:iptables(fileter,nat,mangle,raw)、tcp wrapper
NSSwitch:网络服务转换,实现名称解析,framework框架,platform平台;PAM:插入式认证模块
SMTP/POP3/IMAP4:Mail Server
SELinux:Sercurity Enhenced Linux,安全加强的Linux,操作系统分为ABCD4个级别,A级别最高,D级别最低,Linux和Windows均为C2级别
Linux相对更稳定十年八年不重启不会有影响,Windows则无法做到,但安全性其实相同
C2-->SELinux-->B1 开启SElinux可以将C2级别提升至B1,但是开启后配置过程非常复杂,因此不建议开启

MySQL:

DNS:Domain Name Service 名称解析,Name Resolving 名称转换(背后有查询过程,数据库)
域名:www.magedu.com(主机名或者FQDN:Full Qualified Domain Name,完全限定域名)
FQDN<-->IP 双向转换
数据库内存储内容如下:
172.16.0.1 www.magedu.com.
172.16.0.2 mail.magedu.com.

nsswitch:配置文件:/etc/nsswitch.conf
libnss_files.so
libnss_dns.so

系统启动过程有一行:
hosts: files dns
file:/etc/hosts
dns:DNS服务

stub resolver:名称解析器,通过某个库先找对应文件再找对应服务

hosts:
IPADDR FQDN Ailases
172.16.0.1 www.magedu.com www

IANA:互联网地址名称分配机构,美国机构
ICANN:顶级域名管理组织

TLD:Top Level Domain 顶级域
组织域:.com,.org,.net,.cc
国家域:.cn,.tw,.jp,.hk,.iq,.ir
反向域:IP-->FQDN,正反向均为不同数据库
正向:FQDN-->IP

请求方式分两种:
递归:A请求B找答案,B没有去照C,C返回答案给B,B再返回给A;A只发送一次请求得到答案。
迭代:A请求B找答案,B告诉A去找C要,A再请求C给答案,C返回答案给A;A发送多次请求得到答案。
实际解析过程是迭代方式,用户发起请求给NS服务器,由NS服务器找根,找顶级域,找最终域名解析,反馈给NS,并缓存在自己的服务器中,再反馈给用户。

FQDN-->IP:
www.magedu.com. 绑定多IP,起到负载均衡作用

查询:
递归:只发出一次请求
迭代:可能发出多次请求

解析:
正向:FQDN-->IP
反向:IP-->FQDN

两段式:递归,迭代

DNS:分布式数据库
上级仅知道其直接下级;
下级只知道根的位置;

DNS服务器:
接受本地客户端查询请求(递归)
外部客户端请求:请求权威答案
肯定答案:TTL(缓存时长)
否定答案:TTL(缓存时长)
外部客户端请求:非权威答案

根节点服务器共13个:
a.root-server.net 至 m.root-server.net

主、从DNS:
主DNS服务器:数据修改
辅助DNS服务器:请求数据同步
serial number:有更改序列号加1,辅助发现版本不一致就会同步数据,最长不能超过10位
refresh:刷新时间,多久刷新序列号版本
retry:重试时间
expire:过期时间,多久主DNS无响应定义为主服务器挂了
nagative answer TTL:否定答案的缓存时长
缓存DNS服务器:只负责缓存本地DNS解析
转发器:不缓存只转发请求,即去掉缓存服务的DNS服务器

数据库中的:每一个条目称作一个资源记录(Resource Record,简写:RR)
资源记录的格式:
NAME TTL(缓存时长) IN(表明INTERNET) RRT(资源记录类型) VALUE(数据)
例:
正向:
www.magedu.com. IN A 1.1.1.1
反向:
1.1.1.1 IN A www.magedu.com.

资源记录类型RRT:
SOA(Start of Authority):起始授权记录,表明一个区域内部主从服务器之间如何同步数据以及起始授权对象是谁
ZONE NAME TTL IN SOA FQDN ADMINISTRATOR_MAILBOX (serial number) (refresh) (retry) (expire) (na ttl)
时间:H(小时)、M(分钟)、D(天)、W(周),默认单位是秒
邮箱格式:admin@magedu.com @在记录中表示区域因此要写为 admin.magedu.com
例:在此配置项例;为注释
magedu.com. 600 IN SOA ns1.magedu.com. admin.magedu.com. (2013040101 1H 5M 1W 1D )
NS(Name Server):ZONE NAME --> FQDN
例:magedu.com. 600 IN NS ns1.magedu.com.
magedu.com. 600 IN NS ns2.magedu.com.
ns1.magedu.com. 600 IN A 1.1.1.2
ns2.magedu.com. 600 IN A 1.1.1.5
以上必须成对出现,有表明自身为DNS服务器,也要有自身IP信息
A(addrss):FQDN-->IPV4 常用DNS记录
AAAA:FQDN-->IPV6
PTR(pointer):IP-->FQDN
MX(Mail eXchanger):邮件服务器,ZONE NAME --> FQDN
ZONE NAME TTL IN MX pri VALUE
优先级pri:0-99,数字越小级别越高
magedu.com. 600 IN MX 10 mail.megedu.com.
mail.magedu.com. 600 IN A 1.1.1.3
CNAME(Canonical NAME):FQDN-->FQDN 别名
www2.magedu.com. IN CNAME www.magedu.com.

不常用:
TXT
CHAOS
SRV

域:Domain(逻辑概念)
域的授权由上级决定
区域:Zone(物理概念)
建立正反向区域文件:
正向:
magedu.com. IN SOA
www IN A 192.168.0.1
反向:
0.168.192.in-addr.arpa. IN SOA

PTR:
1.0.168.192.in-addr.arpa. IN PTR www.magedu.com.
简写:
1 IN PTR www.magedu.com.

区域传送的类型:
完全区域传送:axfr
增量区域传送:ixfr

区域类型:
主区域:master
从区域:slave
提示区域:hint
转发区域:forward

创建域名服务器:
magedu.com 172.16.100.0/24

ns 172.16.100.1
www 172.16.100.1,172.16.100.3
mail 172.16.100.2
ftp www

DNS:BIND
Berkeley Internel Name Domain
ISC:互联网系统协会,目前由ISC来维护,www.isc.org可以提供BIND和DHCP下载源码包

检查包安装:
yum list all|grep "^bind"
rpm -ql bind-utils # 查看bind提供的客户端工具
rpm -e bind-libs bind-utils # 卸载原始自带bind已安装包
yum install bind97-libs bind97-utils #安装97版本的bind
bind97-libs:bind所需的库文件
bind97-utils:bind所需的客户端工具
yum info bind97-devel #查看bind97-devel包的详细信息
bind所有头文件和库文件,针对BIND9或者BIND8进行二次开发的时候使用的包
bind-chroot:
默认:named
用户:named
组:named
/var/named/chroot/ # DNS服务的根目录
etc/named.conf # 基于DNS根目录下的配置文件,并非系统根目录下
etc/rdnc.key
sbin/named
var/named/
yum info caching-nameserver
使BIND成为缓存DNS服务器的工具
缓存-->主-->从

bind97:
/etc/named.conf
BIND进程的工作属性
区域的定义
/etc/rndc.key
rndc:Remote Name Domain Controller,远程名称控制服务的秘钥文件
配置信息:/etc/rncd.conf

/var/named/目录下创建数据文件
区域数据文件

/etc/rc.d/init.d/named
{start|stop|restart|status|reload|configtest}
configtest:检查语法错误的

二进制程序:named

yum install bind97 -y # 安装bind97的包
rpm -ql bind97 # 查看安装后生成的所有文件和命令
named-checkconfig
named-checkzone
named.ca
13个根节点服务器的地址,部分根节点有IPV4和IPV6两个地址
named.localhost
本地主机
named.loopback
本地主机名的正反向解析


常用命令:
dig:Domain Information Gropher
-t:指定资源记录类型内的所有结果,如:dig -t NS . 此命令指查询所有根域服务器
后面跟@某个NS服务器也可以在此主机中查找根域服务器信息

service named start 启动dns服务
监听的协议及端口:
53/UDP:查询快速
53/TCP:传输可靠数据时用tcp
953/tcp,rndc:远程域名控制器使用

SOCKET:套接字
IP:PORT

C/S:Client/Server
172.0.0.1:53
172.16.100.1:53

重写配置文件,此配置文件每行都要以;号结尾
vim /etc/named.conf # 权限为640
options {
directory "/var/named";
allow-recursion { 172.16.0.0/16; };
notify yes; # 启动通知功能
};

zone "." IN {
type hint
file "named.ca";
};

zone "localhost" IN {
type master
file "named.localhost";
allow-transfer { none; };
};

zone "0.0.127.in-addr.arpa" IN {
type master
file "named.loopback";
};

zone "mageedu.com" IN {
type master
file "mageedu.com.zone";
allow-transfer { 172.16.100.1; };
};

zone "100.16.127.in-addr.arpa" IN {
type master;
file "172.16.100.zone";
allow-transfer { 172.10.100.2; };
};

根区域:
zone "ZONE NAME" IN {
type {master|slave|hint|forward}
}:

主区域:
file "区域数据文件";

从区域:
file "区域数据文件";
masters {master1_ip;};

更改属组属主:
chown root:named /etc/named.conf
改权限:
chmod 640 /etc/named.conf
检查语法:
named-checkconf # 不报任何信息为无语法错误
named-checkzone "." /var/named/named.ca # 格式均为"区域名" 后跟相应的配置文件
"localhost" /var/named/named.localhost
以上为逐条检测,也可以用下面的命令一次性检查:
service named configtest

启动服务:
service named start
启动后查看日志内容
tail /var/log/messages 可以查看到关于named进程启动情况

临时性的关闭SELinux
#getenforce 查看当前状态
Enforcing 开启状态
#setenforce 0 关闭
#getenforce
Permissive 已关闭
永久关闭SELinux
#vim /etc/selinux/config
SELINUX=enforcing改为permissive或者disabled

检查开启状态:
netstat -tunlp 查看是否有53端口开启

首先将本机DNS解析服务器改为所配置的服务器:
vim /etc/resolv.conf
nameserver 172.16.100.1
检测解析状态:
dig -t NS . # 解析根,可以查看到

设置开机启动:
chkconfig --list named 检查named服务开机启动级别
chkconfig named on 开启开机启动,默认级别345均开启

创建自己的域:
编辑vim /etc/named.conf配置文件
添加正向解析:
zone "mageedu.com" IN {
type master;
file "mageedu.com.zone";
};
保存退出
named-checkconf 检测配置文件语法,不报错则通过
创建mageedu.com.zone文件,区域数据文件中只能放记录,SOA以及TTL值等
vim /var/named/mageedu.com.zone
$TTL 600 # 前面加$符号表示宏,全局引用
@或mageedu.com IN SOA ns1.mageedu.com. admin.mageedu.com. ( 2013040101 1H 5M 2D 6H )
空(表示与上一条内容一致) 600 IN NS ns1
IN MX 10 mail
ns1 IN A 172.16.100.1 任何一个NS记录都必须有个A记录与之相随
mail IN A 172.16.100.2
www IN A 172.16.100.1
www IN A 172.16.100.3
ftp IN CNAME www
保存退出
chmod 640 mageedu.com.zone
chown root:named mageedu.com.zone

named-checkzone "mageedu.com" /var/named/mageedu.com.zone
service named restart 重启服务

dig命令用法:
-t RT资源记录类型 name @IP:表示查询某个名称在某资源记录类型中是否存在,后面@IP表示直接去某个IP查找
-t NS mageedu.com:是否有mageedu.com域下的NS服务器是哪台
例如:
dig -t A www.mageedu.com
QUESTION SECTION:表示你命令的问题是想要www.mageedu.com的所有A记录内容
ANSWER SECTION:表示答案有两条
AUTHORITY SECTION:授权区域段,是由哪个dns承载权威域解析的
ADDITIONAL SECTION:附加段,任何一个NS记录都会有一个A记录与之相随,因此这是授权区域的A记录
dig -x IP:
根据IP查找FQDN

host命令用法:
host -t RT NAME:查询名称的解析结果,RT表示资源类型例如:SOA、NS、MX、A等

nslookup:交互式模式
nslookup:回车后填写DNS server解析
set q=A 表示查询A记录
NAME 输入域可以得到此域A记录所有内容

反向区域配置:
编辑vim /etc/named.conf配置文件
添加:
zone "100.16.172.in-addr.arpa" IN {
type master
file "172.16.100.zone";
};
保存退出
cp -p mageedu.com.zone 172.16.100.zone 直接把正向复制为反向改一下内容即可,-p保留权限
vim 172.16.100.zone # 反向解析中NS不许跟随A记录,并且不需要写MX的mail记录
$TTL 600 # 前面加$符号表示宏,全局引用
@ IN SOA ns1.mageedu.com. admin.mageedu.com. ( 2013040101 1H 5M 2D 6H )
IN NS ns1.mageedu.com. # 反向区域中不能简写
1 IN PTR ns1.mageedu.com.
1 IN PTR www.mageedu.com.
2 IN PTR mail.mageedu.com.
3 IN PTR www.mageedu.com.
保存退出 # 配置中1 2 3表示172.16.100.1-2-3
named-checkconf
named-checkzone "100.16.172.in-addr.arpa" 172.16.100.zone
service named restart
检查结果:
nslookup
set q=PTR
172.16.100.1
set q=PTR
172.16.100.3

godaddy.com 注册域名,无需工信部备案

dig:
aa:Authority ANSWER

泛域解析:
*.mageedu.com. IN A

vim /etc/named.conf 在options全局配置下添加recursion yes;允许递归打开,收到恶意攻击时不会立刻挂掉
options {
recursion yes; # 开启递归功能,针对全局
allow-recursion { 172.16.0.0/16; }; #定义递归范围和来源
allow-query { 范围; }; #只允许哪些范围来查询
allow-transfer { 范围; }; #只允许谁来传送
}

使用dig测试递归模式
dig +recurse -t A www.sohu.com @172.16.100.1 #回车后无反馈结果则为递归未开启,正常会反馈递归解析的过程
dig +norecurse -t A www.baidu.com @172.16.100.1 #不适用递归则通知去照根进行解析
dig +norecurse -t A www.baidu.com @a.gtld-servers.net #则由根反馈baidu的dns服务器的结果
dig +norecurse -t A www.baidu.com @dns.baidu.com #此时才能得到最终的解析结果
使用dig查询区域传送
axfr:完全区域传送
ixfr:增量区域传送
dig -t axfr mageedu.com #得到查询区域内的所有数据
dig -t ixfr=2013040201 mageedu.com #在 2013040201这个版本中更新的增量内容

区域传送存在于主从结构:
allow-transfer { 范围; }; #只允许谁来传送,可以写到全局模式下也可以写到某个zone下

创建从服务器:
在第二台dns服务器安装包:
rpm -e bind-libs bind-utils
yum -y install bind97 bind97-utils

setenforce 0
mv /etc/named.conf /etc/named.conf.orig
scp 172.16.100.1:/etc/named.conf /etc/ # 拷贝主dns的配置文件
vim /etc/named.conf

options {
directory "/var/named";
allow-recursion { 172.16.0.0/16; };
notify yes; # 启动通知功能
};

zone "." IN {
type hint
file "named.ca";
};

zone "localhost" IN {
type master
file "named.localhost";
allow-transfer { none; };
};

zone "0.0.127.in-addr.arpa" IN {
type master
file "named.loopback";
};

zone "mageedu.com" IN {
type slave; #修改
file "slaves/mageedu.com.zone"; #修改
masters { 172.16.100.1; }; #添加
allow-transfer { none; }; #修改
};

zone "100.16.127.in-addr.arpa" IN {
type slave; #修改
file "slaves/172.16.100.zone"; #修改
masters { 172.16.100.1; }; #添加
allow-transfer { none; }; #修改
};

named-checkconf 检查配置文件
serivce named restart #可能无法启动,通过查看/var/log/messages日志发现配置文件权限问题
chgrp named /etc/named.conf #更改为named属组权限,重新启动named服务即可
重启完之后再主DNS端查看/var/log/massages里会有AXFR started和ended信息说明将主域正向反向配置信息完全同步至从服务器
从DNS服务器也可以看到传送开始的日志

此时在主服务器的zone文件下添加
imap IN A 172.16.100.5
保存并记得更改版本号
再查看主从服务器的messages日志
此时未出现日志同步结果,解决方法:
因为zone文件中未标记ns2从服务器的指向,需在正反向zone文件添加从服务器信息:
IN NS ns2
ns2 IN A 172.16.100.2
将从服务器的zone文件删除,重启服务做完全同步

再次在主服务器添加一条新记录,service named reload重新加载,查看日志会有
IXFR started和ended的增量同步信息

rndc:远程域名控制器使用
rndc-confgen > /etc/rndc.conf
cat /etc/rndc.conf
将里面的key开头到结尾的内容全部复制到named.conf文件中去
vim /etc/rndc.conf
进入后冒号输入模式从当前行到结尾倒数第2行内容追加到/etc/named.conf文件中去
:.,$-1w >> /etc/named.conf
vim /etc/named.conf
进入后冒号输入模式从当前行到结尾的所有以#开头并后跟空格的内容全部替换为空,去掉井号注释
:.,$s/^# //g
保存退出
此时再看rndc.conf能看到多了key的内容
使用命令:
service named restart
rndc -c /etc/rndc.conf status #此时日式key文件有问题的话,需要rm /etc/rndc.key删除这个文件
rndc -c /etc/rndc.conf notify "mageedu.com" #手动通知
rndc -c /etc/rndc.conf flush #清空缓存
rndc -c /etc/rndc.conf stop #停止服务
控制远程主机:
控制远程DNS服务器必须更改端口
vim /etc/named.conf
controls {
inet 172.16.100.1 port 953
allow { 172.16.100.2; } keys { "rndc-key"; };
}
保存退出,重启服务

scp /etc/rndc.conf 172.16.100.2:/root/ #将配置文件拷贝到从服务器
到从服务器编辑rndc.conf
vim /root/rndc.conf
将default-server 172.16.100.1 #将服务器更改为主DNS地址,系统时间不同步也会影响DNS的解析

子域授权:
正向区域:
SUB_ZONE_NAME IN NS NSSERVER_SUB_ZONE_NAME
NSSERVER_SUB_ZONE_NAME IN A IP

父域授权子域:看到类型为NS则为域或子域
vim /var/named/mageedu.com.zone
添加ns记录
fin.mageedu.com. IN NS ns1.fin.mageedu.com.
fin.mageedu.com. IN NS ns2.fin.mageedu.com.
ns1.fin.mageedu.com. IN A 172.16.100.8
ns2.fin.mageedu.com. IN A 172.16.100.9

maerket.mageedu.com. IN NS ns1.market.mageedu.com.
ns1.market.mageedu.com. IN A 172.16.100.108

子域无法解析转发:
vim /etc/named.conf
options 下添加如下内容,表示全局生效
forward {only|first} # 如果解析不了,都转发给某个地址
only:只转发给某个地址
first:先转发,转发无果找根
forwarders { 172.16.100.1; }; # 转发给谁,指定转发对象
指定转发域:
zone "ZONE_NAME" IN {
type forward;
forward {only|first};
forwarders { 172.16.100.1; };
};

测试:
dig +trace -t A www.badu.com # 追踪解析过程

DNS视图及日志系统
acl的使用
allow-recursion {}; # 能够被递归的客户端来源
allow-query {}; # 允许查询的客户端
allow-transfer {}; # 区域传送
axfr:完全区域传送
ixfr:增量区域传送

acl ACL_NAME {
172.16.0.0/16;
127.0.0.0/8;
};
如:
acl innet {
172.16.0.0/16;
127.0.0.0/8;
};

allow-query { innet; };
none;
any;

acl策略一般会写到named.conf文件的最上方,options上方
acl innet {
172.16.0.0/16;
127.0.0.0/8;
}
options {
directory "/var/named";
allow-recursion { innet; }; #在options中允许acl策略即可
}

智能DNS
telecom:电信
unicom:联通
两套独立网络
在方庄附近有100G的带宽线路连接两个网络
导致联通和电信之间通信非常慢
网站站点访问最多需要3秒钟,超过5秒网站流量会损失60%

split brain
按照不同网络区分解析结果:
telecom:电信
unicom:联通
web对象缓存
CDN:Content Delivery Network 内容分发网络

DNS View配置:
vim named.conf
view VIEW_NAME {

};
一旦定义了视图,所有的区域都必须定义在视图中
按照模拟设定,划分三个视图:内网、联通、电信
cp /etc/named.conf /etc/named.conf.bak
vim /etc/named.conf
在options下添加
acl telecom {
172.16.0.0/16;
127.0.0.0/8;
};
acl unicom {
192.168.0.0/24;
};

view telecom {
match-clients { telecom; };
zone "mageedu.con" IN {
type master;
file "telecom.mageedu.com.zone";
};
};

view unicom {
match-clients { unicom; };
zone "mageedu.con" IN {
type master;
file "unicom.mageedu.com.zone";
};
};

创建新的区域文件
vim /var/named/telecom.mageedu.com.zone
$TTL 43200
@ IN SOA ns1.mageedu.com. admin.mageedu.com. (
2013040201
1H
10M
7D
1D )
IN NS ns1
IN MX 10 mail
ns1 IN A 172.16.100.1
mail IN A 172.16.100.2
www IN A 172.16.100.3
保存退出
chgrp named /var/named/telecom.mageedu.com.zone
chmod 640 /var/named/telecom.mageedu.com.zone
cp -p /var/named/telecom.mageedu.com.zone /var/named/unicom.mageedu.com.zone
vim /var/named/unicom.mageedu.com.zone
$TTL 43200
@ IN SOA ns1.mageedu.com. admin.mageedu.com. (
2013040201
1H
10M
7D
1D )
IN NS ns1
IN MX 10 mail
ns1 IN A 172.16.100.1
mail IN A 192.168.0.16
www IN A 192.168.0.17
保存退出
重启服务
service named restart
分别在192和172网段的客户端使用dig -t A www.mageedu.com查看解析结果分别是自己的网络IP

本地客户端192和172地址都有
nslookup
server 172.16.100.1 # 指定DNS Server
set q=A # 设置要查询的记录类型
www.mageedu.com
返回结果是172.16.100.3

dnspod:
中国著名的免费智能DNS提供商
www.dns.la
国内排名第二的智能DNS提供商,马哥创建

DLZ技术创建智能DNS
bind-sdb也是bind自带的将DNS数据放入数据库的工具

DNS开启日志功能:互联网中使用不建议开启日志,对DNS服务器磁盘IO消耗较大
vim named.conf
在options中加入
querylog yes; # 即可开启日志功能,在/var/log/messages中可以看到查询解析日志

DNS日志系统可以定义只记录那些内容:
channel:日志保存位置
一个category可以被定义到多个channel,但一个channel只可以定义一个category
syslog
file:自定义存放文件

日志级别:
critical、error、warning、notice、info:默认级别、debug、dynamic

category:日志愿,可自定义日志来愿
查询
区域传送
default、general、queries(查询操作产生日志)、xfer-in(从服务器传入的信息)、config(配置文件产生的问题)、network(网络相关问题)、notify(通知相关内容)、security(拒绝的查询请求)、
使用示例:
vim /etc/named.conf
添加
logging {
channel querylog {
file "/var/log/named/bind_query.log" versions 5 size 10M; #大小10M,日志滚动大小,到10M及产生另一个文件,最多保存5个版本
severity dynamic; # 日志级别是dynamic
print-time yes;
print-severity yes;
print-category yes;
};

channel xfer_log {
file "/var/log/named/transfer.log" versions 3 size 10k; #大小10M,日志滚动大小,到10M及产生另一个文件,最多保存5个版本
severity dyebug 3; # 日志级别是debug 3级别
print-time yes;
};

category query { querylog; }; # 查询的信息保存至querylog定义的文件中
category xfer-out { xfer_log; };
};

模拟传输过程:
dig -t axfr mageedu.com @172.16.100.1
查看transfer.log就可以看到日志结果

注意:查询和安全最好不要开启,因为记录内容过多,更新相关信息应该开启。

dns服务器性能测试工具:
dnstop工具:监控dns服务器每秒可以接受多少查询,并记录查询哪个域名。评估服务器查询能力。
queryperf:压力测试,bind包自带,文件中解析非常快,而数据库中主要看硬件性能,解析700-800个就非常不错,而文件则会达到10000个查询每秒是没有问题的

queryperf使用方式:
源码包安装:
tar xf bind-9.7.4.tar.gz
cd bind-9.7.4
cd contrib
cd queryperf
yuminstall gcc make
./configure
make
cp queryperf /bin/
使用:
vim test # 把要解析的域名及类型写入到测试文件中
www.mageedu.com A
mageedu.com NS
mageedu.com MX
保存退出
测试命令:
queryperf -d test -s 172.16.100.1 # -d指定测试文件,-s指定域服务器
会产生最终结果
queries per second:1899.936669 qps # 查询内容过少可能时间不准确,多写一些测试域名
写入20万条解析后结果:
queries per second:15025.942721 qps
跨主机进行解析,在其他服务器进行测试结果:
queries per second:10328.214217 qps

dnstop使用:
源码包安装:
tar xf dnstop-20110502.tar.gz
cd dnstop-20110502
./configure
make
报错缺少软件包libcap(抓包工具)
yum -y install libcap
yum -y install libpcap-devel
make clean
重新./configure
make
make install
默认安装路径:/usr/local/bin下
使用:
dnstop -4 -i 172.16.100.1 -R -Q eth0 # -4是指定ipv4 -i是指定dnsserver的IP地址 -Q统计查询数 -R统计响应数
查看到动态统计内容,此时配合压力测试,可以监控到dns服务器工作状态

注:named.conf注释使用//,与C语言注释方式类似。多行注释方法:在注释首行 /*在注释末行输*/ 完成多行注释

将日志记录内容注销掉后,性能会得到明显提升。

DHCP服务:Dynamic Host Configration Protocol 前身为bootp
lease:租约

DHCP分配过程(广播):
client--> DHCPDISCOVER 发现报文
server--> DHCPOFFER 服务端回应报文
client--> DHCPREQUEST 应答报文决定使用DHCP分配IP
server--> DHCPACK 确认报文
续租过程(单播):
client--> DHCPREQUEST 应答报文继续使用DHCP分配IP
server--> DHCPACK 确认报文

注:因为路由无法广播,因此DHCP服务器无法跨网络使用
跨网DHCP功能:
DHCP Relay:DHCP中继器

DHCP安装配置:
yum list all | grep dhcp # 检查安装
yum -y install dhcp # 安装
rpm -ql dhcp #查看安装相关文件
/etc/dhcpd.conf:dhcp主配置文件
/etc/sysconfig/dhcpd:dhcp服务进程
/etc/sysconfig/dhcrelay:dhcp中继进程
/usr/sbin/dhcpd:dhcp服务启动进程
/usr/sbin/dhcrelay:dhcp中继器启动进程
/var/lib/dhcpd/dhcpd.leases:租约信息记录文件

vim /etc/dhcpd.conf # 内容为空,让拷贝配置文件dhcpd.conf.sample覆盖
cp /usr/share/doc/dhcpd-3.0.5/dhcpd.conf.sample /etc/dhcpd.conf
vim /etc/dhcpd.conf
将网段范围,网关,子网,DNS主副服务器,可分配的网络地址段落,默认租约时间和最大租约时间以秒为单位。其他不用修改,保存退出即可。
dhcp服务器端监听:67/udp
客户端:68/udp

netstat -unlp # 查看监听
绑定IP和mac地址:
vim /etc/dhcpd.conf
添加:
host ns {
hardware ethernet 00:0C:29:77:A2:EC;
fixed-address 172.16.100.33;
保存退出
service dhcpd restart 重启服务

tail /var/lib/dhcpd/dhcpd.leases # 可以看到租约信息

常用命令:
dhclient:down掉某个网卡,直接执行,可以看到网卡分配地址续租详细过程
-d:工作在前台,ctrl+c结束进程,无需killall dhclient进程

HTTP:HyperText Transfer Protocol:超文本传输协议
超链接:链接之间跳转

web:
http/0.9:仅纯文本(超链接),ASCII
HTML:HyperText Mark Language:超文本编辑语言
<h2>Title</h2> 标记Title字体显示格式

Browser:客户端浏览器

URI:Uniform Resource Indentifier 统一资源标识符,全局范围内,资源访问路径的命名方式
统一:路径格式上的统一

URL:Uniform Resource Locator 统一资源定位符,URI的子集,互联网范围内的统一表示

protocol://host:port/path/to/file
如:
http://www.magedu.com/download/linux.tar.gz

web资源:http://www.magedu.com/logo.gif
多个资源很可能被整合为一个html文档

web对象:与web资源相同

HTTP方法:
GET:获取web资源到本地
http/1.0:PUT,POST,DELETE
MIME:Multipurpose Internet Mail Extension,多用途互联网邮件扩展
SMTP:Simple Mail Transmission Protocol,简单邮件传输协议,只能传输纯文本
MIME:将非文本数据在传输前重新编码为文本格式,接收方能够用相反的方式将其重新还原为原来的格式,还能够调用相应的程序来打开此文件。
Base64:文本编码格式

协议首部:
image/jpeg:会标记文件类型和格式,来标记打开其的相应程序

动态效果:ActiveX、Flash
Java,Applet,JRE

动态网页:服务器端存储的文档非HTML格式,而是编程语言开发的脚本,脚本接受参数之后在服务器端执行一次,运行完成后会生成HTML格式的文档,把生成的文档发给客户端;

web:index.php脚本,服务器根据扩展名通过某种协议调用相应的PHP解释器来运行index.php,将生成的HTML文档发送给客户端

index.html:
引用N个web对象:URL
动态网页:包含静态内容和动态内容
动态内容部分才需要运行

IP首部:
Source IP
Destination IP
TCP首部:
Source Port
Destination Port
http首部:
GET /2.html
Host:www.magedu.com(虚拟主机)
HTTP报文:请求报文,响应报文
请求报文语法:
<method><request-URL><version> 资源获取方法 请求资源URL 资源版本号
<headers> 首部
空白行必须留
<entity-body> 报文主体
响应报文语法:
<version><status><reason-phrase> 版本 状态码 详细解释成功错误的信息
<headers>

<entity-body>

状态码:5类
1xx:纯信息
2xx:“成功”类状态信息(200:正常响应)
3xx:重定向类的信息(301:永久重定向、302:临时重定向、304:请求无改变用缓存即可)
4xx:客户端错误类状态信息:(404:请求了不存在的文件)
5xx:服务器端错误类状态信息:

请求报文样例:
GET / HTTP/1.1 请求访问/目录为默认页面,http协议版本1.1
Host:www.magedu.com 首部名称
Connection:keep-alive 首部

响应报文:
HTTP/1.1 200 OK 响应协议版本 状态码 详细信息
X-Powered-By:PHP/5.2.17 首部通过PHP解释器解析
Very:Accept-Encoding,Cookie,User-Agent 额外标记变化类内容
Cache-Control:max-age=3,must-revalidate 控制客户端能否缓存
Content-Encoding:gzip 内容编码机制压缩后发布
Content-Length:6931 内容长度

上面两个报文的第一行通常称作报文"起始行(start line)";后面的标签格式的内容称作首部域(Header field),每个首部域都由名称(name)和值(value)组成,中间用逗号分隔。另外,响应报文通常还有一个称作Body的信息主体,即响应给客户端的内容。

web服务器的主要操作:
1、建立连接--接受或拒绝客户端连接请求;
2、接收请求--通过网络读取HTTP请求报文;
3、处理请求--解析请求报文并作出响应的动作;
4、访问资源--访问请求报文中相关的资源;
5、构建响应--使用正确的首部生成HTTP响应报文;
6、发送响应--向客户端发宋生成的响应报文;
7、记录日志--当已经完成的HTTP事务记录进日志文件。

每个web资源都需要单独请求单独响应

http/1.1:
增强了缓存
增加了长连接:TCP三次握手建立连接后,长时间连接状态持续传输文件,并发量过大时会阻塞。长连接对服务器性能影响较大
1、设置连接超时时长
2、设置连接次数

Server模型:
1、单进程/单线程服务器模型
一个进程处理一个请求,后面的请求排队
2、多进程/多线程服务器模型
一个进程接受请求后生成子进程处理,再接受另一个请求生成另一个子进程处理
3、单进程多请求
事件驱动结合状态反馈通知,一个进程负责多个请求,均有一个进程响应,定期扫描请求完成情况反馈响应,多个用户请求同一个文件时可以统一响应,减少资源使用量
4、多进程多请求(最优)
多进程事件驱动模型,每个进程都可以接受多个请求,请求减少时进程可以根据请求数量减少
httpd,MPM
prefork
work
event

C/S架构:
C:Client Agent (browser,spider)
S:Server

Client-->request-->Server
URL
Server-->response-->Client

HTTP Method
GET,HEAD,POST,PUT,DELETE,TRACE,OPTIONS,CONNECTION

客户端浏览器:
IE
Firefox
Chrome
Opera
Safari
Server:
Apache,httpd
IIS
Nignx
lighttpd
thttpd
应用程序服务器:不仅可以处理静态内容,还可以处理某种动态内容
IIS
Tomcat(apache,JSP,open source)java
Websphere(IBM,JSP,commodity)java
Weblogic(Oracle,JSP,commodity)java
JBoss(RedHat,核心是Tomcat)

最流行的web服务器统计:
www.netcraft.com 每半年或三个月统计一次web服务器排名
第一名:apache 58%
第二名:Microsoft 16%
第三名:Nginx 12%
第四名:Google 3.48%

web代理:
web代理服务器工作与web客户端和web服务器之间,它负责接收来自于客户端的HTTP请求,并将其转发至对应的服务:而后接收来自于服务端的响应,并将响应报文回送至客户端。

httpd安装配置:

apache:A Patchy Server

开源组织基金会:
FSF:Free Software Foundation ,GNU组织,GPL
ASF:Apache Software Foundation 阿帕奇软件基金会 www.apache.org
web:httpd
Tomcat(JSP应用发布程序)
Hadoop(并行处理环境,提供高性能处理环境的框架)

web:http://httpd.apache.org

httpd:
web Server,Open Source
2.2主流,2.4最新,2.0稳定著称,1.3老版本现已停止更新

httpd特性:
事先创建进程:
按需维持适当的进程
模块设计,核心比较小,各种功能都通过模块添加(包括PHP)
支持运行配置,支持单独编译模块
支持多种方式的虚拟主机配置
Socket:IP:Port
虚拟主机:
基于IP的虚拟主机;
基于端口的虚拟主机;
基于域名的虚拟主机;
支持HTTPS协议(mod_ssl)
支持用户认证
支持基于IP或主机名的ACL
支持每目录的访问控制
支持URL重写,/imeage/a.jpeg,/bbs/images/abc.jpeg

nginx:多进程响应N用户响应模型

RedHat(httpd):
rpm包:容易出现需要的模块未编译,不需要的却编译了,版本较老
源码编译:

HTTPD:SELinux(事先让其处于permssive,disabled状态)
getenforce查看SELinux状态
使用setenforce 0 禁用,临时方法
vim /etc/sysconfig/selinux
vim /etc/selinux/config
SELINUX=enforcing改为permssive # 为方便日后启用,最好改为permssive

httpd:
/usr/sbin/httpd (MPM:prefork)
一个httpd进程:root用户,root组 (master process) 主导进程
其余httpd进程:apache用户,apache组 (wrker process)工作进程
/etc/rc.d/init.d/httpd
port:(80/tcp),(ssl:443/tcp)
/etc/httpd:工作根目录,相当于程序安装目录
/etc/httpd/conf:配置文件目录
主配置文件:httpd.conf
/etc/httpd/conf.d/*.conf #也都是相关配置文件,只不过在主配置文件中用include加载到一起了
/etc/httpd/modules:模块目录
/etc/httpd/logs --> /var/log/httpd:日志目录
日志文件有两类:访问日志access_log,错误日志:err_log
/var/www/
html目录:静态页面所在路径
cgi-bin目录:动态内容所使用路径
cgi:Common Gateway Interfave,让web服务器能够让额外的应用程序处理动态内容
Client --> httpd(index.cgi)--> Spawn Process(index.cgi)--> httpd --> Client
perl,python,java(Servlet,JSP),php,

fastcgi:

程序:指令和数据组成 cpu-bound CPU密集型应用
数据:数据库服务 cpu-bound CPU密集型应用

httpd安装:
yum -y install httpd httpd-manual # httpd为主程序,httpd-manual为帮助手册,安装手册后再访问根目录后面输入manual访问即可
安装完成后查看生成的文件
rpm -ql httpd | less
存在配置文件,模块,日志等常规文件
/usr/bin/ab # apache压力评估工具,常用
service httpd start # 启动服务
netstat -tnlp|grep :80 # 查看监听
pa aux|grep httpd # 查看进程
httpd配置:
cd /etc/httpd/conf
cp httpd.conf httpd.conf.bak1181023 # 先执行备份,如果改错可以保证恢复前一版
grep "Section" httpd.conf # 会显示主配置文件的三个主要段落,1、全局配置;2、主服务器配置;3、虚拟主机配置

httpd.conf全局配置内容:
directive value
指令不区分大小写
value则根据需要有可能要区分

ServerTokens OS # 定义打开apache页面可输出系统信息内容的详细程度
ServerRoot "/etc/httpd" # 服务器根目录
PidFile run/httpd.pid # 进程pid号存放
Timeout 120 # 创建连接超时时长
KeepAlive Off|On # 是否使用长连接,用户量不是很大时打开优化性能
MaxKeepAliveRequests 100 # 打开长连接个数设定,0为不限定
KeepAliveTimeout 15 # 长连接超时时长,单位秒
注:具体参数设定值,可以使用ab或者LoadRunner进行压测后优化参数值设定

MPM:Multi Path Modules,多道处理模块
mpm_winnt:windows专用线程处理机制
perfork:一个请求用一个进程响应,预先生成进程 # 2.2版本默认使用perfork机制,稳定但并发量大时性能较差
worker:一个请求用一个线程响应,基于线程工作,启动多个进程(默认两个),每个进程生成多个线程 # 性能较高,避免进程间争抢资源就会加锁,因此经测试,linux下性能不及perfork
event:一个进程处理多个请求 # 2.4版本后默认就是event机制,2.2中event是测试模型,不建议使用

使用 httpd -l查看当前服务器支持的模型类型,当前只支持prefork模型
rpm -ql httpd |grep bin # 可以看到/usr/sbin/httpd.event和/usr/sbin/httpd.worker文件
使用这两个文件即可开启响应的模型模块
vim /etc/sysconfig/httpd
HTTPD=/usr/sbin/httpd.worker 取消注释,即可开启worker模式
模块配置属性:
<IfModule prefork.c>
StartServers 8 # 开启时启动进程数
MinSpareServers 5 # 最少空闲进程数
MaxSpareServers 20 # 最大空闲进程数
ServerLimit 256 # MaxClients的上限值,硬限制
MaxClients 256 # 最大客户端数,最多可连接进来的请求
MaxRequestsPerChild 4000# 一个进程最多响应多少次用户请求,达到后就会被Kill掉,重新生成
</IfModule>

<IfModule worker.c>
StartServers 2 # 开启时启动进程数
MaxClients 150 # 最多客户端请求数
MinSpareThreads 25 # 最小空闲线程数
MaxSpareThreads 75 # 最大空闲线程数
ThreadsPerChild 25 # 每个进程可生成多少个线程
MaxRequestsPerChild 0 # 每个进程接受多少次请求,因为由线程接受,因此不做限定
</IfModule>

Listen 80 # 监听为80端口

LoadModule auth_basic_module modules/mod_auth_basic.so # 加载模块,加载指令 模块名称 模块路径

Include conf.d/*.conf # 将conf.d目录下的所有.conf结尾的配置文件全部加载进主配置文件中

User apache # 启动进程用户
Group apache # 启动进程组

主要Server配置端:
主server配置文件中的配置绝大多数都能在虚拟主机中使用
httpd.conf Main Server配置内容:
vim httpd.conf
ServerAdmin root@localhost
ServerName www.example.com:80 # 默认不启用,如果不启用会反向解析当前IP地址,解析到的主机名为名称,否则会报错
UseCanonicalName Off # 自身名称,默认关闭
DocumentRoot "/var/www/html" # 文档根目录,存放web页面程序的
<Directory "/var/www/html"> #在此内容定义URL根目录是如何被访问的
Options Indexes FollowSymlinks #根目录中所有页面程序的展示属性;
None:不支持任何选项,设置此项最为安全;
Indexes:允许索引目录,生成环境建议关闭;
FollowSymlinks:跟随符号链接,允许访问符号链接文件所指向原文件,生成应关闭,并且降低服务器性能;
Includes:允许执行服务端包含(SSI:格式的网页文件);
SymLinksifOwnerMatch:允许执行符号链接原文件,但属主必须跟httpd进程属主相符合;
ExecCGI:允许运行CGI脚本;
MultiViews:多功能视图,内容协商机制,较消耗资源,根据客户端匹配语言或其他相应内容
All:允许所有功能
AllowOverride None # 允许覆盖下面两项内容
FileInfo:
AuthConfig:需要建立一个访问用户名和密码文件,允许此文件中的用户使用密码登录后才能访问
AuthType basic:基本认证
AuthName "Restricted Files":用户认证时显示名称,告知用户为什么认证
AuthUserFile /usr/local/apache/passwd/passwords:指定认证用户列表文件
AuthUserFile /usr/local/apache/passwd/groups:指定认证组列表文件
Require user marion:只允许此用户才可以登录
Require user GroupName:只允许某个组访问
Require valid-user:只要出现在文件中的用户均可登录
htpasswd:专用创建httpd访问用户列表的命令
-c:第一次创建使用选项,已有的文件切忌使用,会将原文件覆盖
-m:已MD5方式加密存放
-D:删除用户
例子:
htpasswd -c -m /etc/httpd/conf/htpasswd hadoop # 创建文件并添加hadoop用户,回车后输入密码即可完成创建
再次添加去掉-c使用:htpasswd -m /etc/httpd/conf/htpasswd tom 即可
组文件自行创建vim htgroup 内容添加 myusers:hadoop tom # 组名称冒号后跟用户名,之间加空格

Limit:
Order allow,deny # 用于定义基于主机的访问控制功能的,IP,网络地址或主机定义访问控制机制,此项为先允许后拒绝,默认项为拒绝
allow from 192.168.0.0/24 # 只允许此网段访问
地址表示方式:IP,network/netmask,HOSTNAME,DOMAINNAME,Partial IP:172.16,
deny from
Allow from all # 允许所有访问
<Directory>
DirectoryIndex index.html index.html.var # 访问索引,按照顺序逐一访问,如果都没有就会列出文件列表
AccessFileName .htaccess # 每目录的访问控制,会严重影响apache的效率,因为层级设定,一般不启用
<Files ~ "^\.ht"> # 以.ht开头的文件访问权限
Order allow,deny
Deny from all
</Files>
TypesConfig /etc/mime.types # mime多功能互联网邮件扩展,开启HTTPD协议支持mime类型
DefaultType text/plain # 如果未指定类型,默认是纯文本类型
<IfModule mod_mime_magice.c> # 开启mime_magice.c模块
MIMEMagiceFile conf/magic
</IfModule>
HostnameLookups Off # 访问日志中是否记录主机名,默认关闭,影响性能
ErrorLog logs/error_log # 定义错误日志位置
LogLevel warn # 定义日志级别
LogFormat "%h %l %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined # 定义之日格式
%h:远端客户地址
%l:远端用户登录名称,一般为-,因为对方不对将远端用户系统名暴露出来
%t:访问时间
%r:前后的\表示转译就表示“本身,需要用引号隔开的内容,请求报文第一行即访问方法
%>s:最后一次请求的状态码
%b:影响报文的大小
%{Referer}i:上一个访问页面,首部
%{User-Agent}i:浏览器类型
CustomLog logs\access_log combined 指定访问日志使用上面定义的combined日志格式记录

Alies /icons/ "/var/www/icons/" # 路径别名,指定某个路径为某个简写别名,前后格式一定一致
<Directory "/var/www/icons">
Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all
</Directory>

httpd -t # 命令用于检测当前web server配置文件语法规范的
elinks http://172.16.100.1 纯文本浏览器,用于打开纯文本页面
-dump:显示网页后立即退出,不进入交互模式
-source:显示网页源代码
httpd -M # 查看所有web服务器中支持的模块,mod_userdir.c表示是否支持用户在自己家目录中建立个人网页
<IfModule mod_userdir.c>
UserDir disabled # 默认不允许,启用将其注释掉
UserDir public_html # 取消注释这行,启用家目录访问
</IfModule>
需要给文件设定执行权限,chmod o+x /home/hadoop
如果允许则可通过 http://172.16.100.1/~hadoop/访问自己家目录网页
PV:Page View 网站访问量,网站页面被访问次数量
UV:User View 用户访问量,也就是独立IP访问的量

apache虚拟主机:
中心主机
虚拟主机:
apache服务:
服务于多个不同的站点;
基于IP
IP1:80
IP2:80
基于端口
IP:80
IP:8080
基于域名
IP:80
主机名不同
www.mageedu.com
www.a.org
www.b.net

apache 2.2
启用NameVirtualHost
apache 2.4

ServerName:
DocumentRoot:
Directory定义访问文件系统路径属性方法
<Directory "/www/a.org">
Option
AllowOverride
</Directory>

Location定义URL访问路径属性方法
<Location "/images">

</Location>
开启下面的Location可以显示当前服务器的状态信息,一般默认关闭,但可以设定对某个主机开放访问
<Location "/images">
SetHandler server-status # SetHandler是执行一个动作的标记命令,后跟要执行的动作
Order Deny,Allow
Deny from all
Allow from .foo.com # 只有.foo.com的访问被允许
</Location>

指定可执行CGI脚本路径
ScriptAlias
CGI协议:Common Gateway Interface 动态网关接口

客户端动态脚本:客户端访问时将脚本下载到本地客户端执行
服务端动态脚本:在服务端执行脚本,将结果返回客户端

MVC:

先取消中心主机,注释中心主机的DocumentRoot即可。
虚拟主机的定义:
<VirtualHost HOST>

</VirtualHost>

HOST写法:
基于IP:HOST写法
IP1:80
IP2:80
基于端口:
IP:80
IP:8080
基于域名:
*:80
ServerName不同即可

创建方法:
在httpd.conf中写也可以或者创建新的virtual.conf文件
基于IP的虚拟主机写法:
vim /etc/httpd/conf.d/virtual.conf
<VirtualHost 172.16.100.1:80>
ServerName hello.magedu.com
DocumentRoot "/www/magedu.com"
</VirtualHost>

<VirtualHost 172.16.100.2:80>
ServerName hello.magedu.com
DocumentRoot "/www/a.org"
</VirtualHost>

基于端口的虚拟主机写法:首先在httpd.conf主配置文件中添加Listen 8080 添加8080的监听,否则apache不会解析8080端口
<VirtualHost 172.16.100.1:80>
ServerName hello.magedu.com
DocumentRoot "/www/magedu.com"
CustomLog "/var/www/httpd/magedu.com/access_log combined"
</VirtualHost>

<VirtualHost 172.16.100.1:8080>
ServerName www.a.org
DocumentRoot "/www/a.org"
CustomLog "/var/www/httpd/a.org/access_log combined"
</VirtualHost>

基于域名的虚拟主机写法:
NameVirtualHost 172.16.100.2:80
<VirtualHost 172.16.100.2:80>
ServerName www.a.org
DocumentRoot "/www/a.org"
<Directory "/www/a.org">
Options none
AllowOverride authconfig
AuthType basic
AuthName "Restrict area."
AuthUserFile "/etc/httpd/.htpasswd" # 用户访问此站点需登录
Require valid-user
</Directory>
</VirtualHost>

<VirtualHost 172.16.100.2:80>
ServerName www.d.gov
DocumentRoot "/www/d.gov"
CustomLog "/var/www/httpd/d.gov/access_log combined"
<Directory "/www/d.gov">
Options none
AllowOverride none
Order deny,allow
Deny from 172.16.100.177 # 拒绝177的IP访问此站点
</Directory>
</VirtualHost>
测试基于域名的虚拟主机需要在本地hosts文件中将两个解析都写入,做到可以本地解析

定义好log日志的位置后更改属组属主为apache权限

设定默认虚拟主机:必须写在名称虚拟主机第一个位置
<VirtualHost _default_:80>
DocumentRoot "/www/default80"
# ...
</VirtualHost>

<VirtualHost _default_:*>
DocumentRoot "/www/default"
# ...
</VirtualHost>

基于openssl的https服务配置
1、安装ssl模块
httpd -M # 查看是否支持ssl模块
yum install mod_ssl # 安装模块
rpm -ql mod_ssl # 查看生成的文件
2、CA生成
cd /etc/pki/CA
(umask 077; openssl genrsa -out private/cakey.pem 2048) # 生成私钥文件
ls -l private/cakey.pem # 查看权限是600
生成自签证书
vim /etc/pki/tls/openssl.cnf
countryName_default = CN # 默认国家名称改为CN
stateOrProvinceName_default = HeBei # 默认省份名称随意改
localityName_default = ShiJiaZhuang # 默认城市名称
0.organizationName_default = MageEdu # 默认组织名称
organizationalUnitName_default = Tech # 默认部门名称
保存退出
openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3655 # 生成CA自签证书
Common Name 填写主机名称 :ca.magedu.com
Email Address :admin@magedu.com
完成自签证书制作
vim ../tls/openssl.cnf
[ CA_default ]
dir =/etc/pki/CA # 更改目录位置
保存退出
mkdir certs crl newcerts # 创建配置文件中的目录
touch index.txt # 创建文件
echo 01 > serial
准备完成
3、回到服务器端
cd /etc/httpd/
mkdir ssl
(umask 077; openssl genrsa 1024 > httpd.key) # 生成服务器端私钥文件
openssl req -new -key httpd.key -out httpd.csr # 生成CA证书
需要输入内容一定和CA服务器生成内容保持一致
CN
HeBei
ShiJiaZhuang
MageEdu
Tech
hello.magedu.com # 这里一定填写服务器端你需要使用ssl服务的站点名称
hello@magedu.com
后面默认即可
证书签署请求完成
scp httpd.csr 172.16.100.8:/tmp # 拷贝到CA服务器
4、回到CA服务器签署证书
openssl ca -in /tmp/httpd.csr -out /tmp/httpd.crt -days 3650
确认签署选择y
最终确认y
签署完成
cat /etc/pki/CA/index.txt # 可以看到01生成
cat /etc/pki/CA/serial # 显示02,表示下一个注册为02
5、回到服务器端拷贝证书
scp 172.16.100.8:/tmp/httpd.crt ./
启用服务器端使用证书
cp /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.bak
vim /etc/httpd/conf.d/ssl.conf
<VirtyalHost _default_:443> # 将_default_改为发布web请求的服务器IP地址
ServerName hello.magedu.com # 含多个虚拟主机的写清楚使用ssl的站点名称
DocumentRoot "/www/magedu.com" # 填写此虚拟主机对应的发布目录
SSLCertificateFile /etc/httpd/ssl/httpd.crt # 填写证书文件位置
SSLCertificateKeyFile /etc/httpd/ssl/httpd.key # 私钥文件位置
保存退出即可
service httpd restart 重启服务
查看监听端口是否有443端口
6、使用客户端访问https://hello.magedu.com访问测试
提示没有可信证书
将服务器CA证书拷贝到本地一份
将/etc/pki/CA/cacert.pem 拷贝到本地
在本地重命名为cacert.crt,双击安装证书,将所有的证书放入下列存储选项中点击浏览选择受信任的根证书颁发机构,完成证书安装
再次访问https://hello.magedu.com
注意:一个地址只能建立一个ssl虚拟主机


php相关概念及配置:
MIME:可以使HTTP协议传输非文本格式的文件,例如:.mp3
动态网站:根据客户端请求执行程序后,返回不同执行结果的。
JVM:Java Virtual Machine java是运行一次到处执行的语言程序,在多个平台运行
CGI:让服务器端可以执行程序的协议
web服务器进程根据请求程序不同调用对应执行环境来运行对应的程序文件,并且将结果取回至web进程的协议
编程语言:
静态语言:编译型语言,强类型,先编译才能运行,适合底层运行,性能优势大。针对实时场景,性能要求高的场景:驱动程序、数据库服务器软件、操作系统等
C,C++,JAVA
优势:性能好
劣势:每一次改动都需要重新编译,开发周期长,维护成本大
动态语言:解释型语言,弱类型,无需编译,变量可直接拿来用,直接运行程序
shell,perl,python
优势:便于维护,众多共享模块,开发周期短,
劣势:性能差
Facebook
动态语言-->静态语言
php --> Hiphop(转换器) --> C++ 提高web性能

PHP:Hypertext Preprocessor 超文本预处理器
php解释型语言
php source code --> 编译成二进制 --> 执行二进制格式
zend:opcode 编译好的php进程
opcode缓存器,共享编译好的opcode使用
常见加速器:
APC(Alternative PHP Cache)
eAccelerator
XCache 最常用,快速且稳定
Zend Opeimizer和Zend Guard Loader
NuSphere PhpExpress

PHP源码目录结构:
build:主要放置一些跟源码编译相关的文件,比如开始构建之前的buildconf脚本及一些检查环境的脚本等
ext:官方的扩展目录,包括了绝大多数的PHP的函数的定义和实现,如:array系列,pdo系列,spl系列等函数的实现
个人开发的扩展在测试时也可以放到这个目录,以方便测试等。
main:这里存放的就是PHP最为核心的文件,是实现PHP的基础设施,这里和zend引擎不一样,zend引擎主要实现语言最核心的语言运行环境。
zend:zend引擎的实现目录,比如脚本的词法语法解析,opcode的执行以及扩展机制的实现等等。
pear:PHP扩展与应用仓库,包含PEAR的核心文件
sapi:包含了各种服务器抽象层的代码,例如:apache的mod_php,cgi,fastcgi以及fpm等等接口
TSRM:PHP的线程安全是构建在TSRM库之上的,PHP实现中常见的*G宏通常是对TSRM的封装,TSRM及线程安全资源管理器
tests:PHP的测试脚本集合,包含PHP各项功能的测试文件。
win32:这个目录主要包括windows平台相关的一些实现,比如:sokcet的实现在windows下的*Nix平台不太一样,同时也包括了windows下编译PHP相关的脚本。

嵌入式web开发语言

apache:
DSO:dynamic shared object
php_mod:合并处理静动态内容,整合为一个进程处理
FastCGI:
fpm:快速php模块
apache为客户端后端php为服务器提供php服务给apache

apache+php:
CGI
Modules:最简单的
FastCGI:配置php服务

Nginx+fpm:更适合FastCGI

php安装配置:
yum install php53-mbstring

数据库及MySQL:

程序:指令+数据
数据库查找用户:
排序:
索引:
二分法索引:针对用户排序取中间ID进行对比依次缩小范围查找,平均14次可以查找到最终结果
B+树索引:搜索码

程序与数据库连接方式:
连接数据库通过API连接:非常不方便
API就是一堆function()函数
优化由数据库提供ODBC统一接口连接:
各类程序语言使用各自的驱动翻译成数据库识别的API来连接:

DBMS:DataBase Management System
用户视图:
物理视图:
数据的组织结构:
层次型
网状型
关系型:主流
RDBMS:Relational DataBase Management System
1、数据库创建、删除
2、创建表、删除表、修改表
3、索引的创建、删除
4、用户和权限
5、数据增、删、改
6、查询

DML:Data Manapulate Language:数据操作语言
INSERT,REPLACE,UPDATE,DELETE
DDL:Data Defination Language:数据定义语言
CREATE,ALTER,DROP
DCL:Data Control Language:数据控制语言
GRANT,REVOKE

RDBMS软件:egreSQL第一款数据库软件
Oracle、Sybase、Infomix 三大数据库厂商
SQL Server
MySQL、PostgreSQL、EnterpriseDB

MySQL被Oracle收购后又延伸出更多开源SQL版本
MySQL-->MariaDB,Percona

反关系模型:NoSQL非关系型数据库
MongoDB
Redis
HBase

MySQL初步,数据类型及SQL语句

DBMS:
数据挂了你独立性;
有效的完成数据存取;
数据完整性和安全性;
数据集中管理;
开发存储与故障恢复;
减少应用程序开发时间;

SQL:结构化查询语言 ANSI,遵循标准
sql86,sql89,sql92,sql99

SQL命令:
分析器:词法分析,语法分析
计划执行器:有多少种方式可执行
优化器:选择最优的执行方式
文件存取:选择一种存取方式进行数据的存取
缓存器:将文件读至缓存器中
磁盘空间管理器:实现对数据存储至磁盘中的规划管理
故障恢复管理器:出现数据库管理器出现故障时,保障其处理数据能够恢复原始状态
事务管理器:处理数据事务
锁管理器:处理并发时数据锁定机制

MySQL:
Community Edtion:社区版
Enterprise Edtion:企业版,区别在于商业版有增强的性能监控工具,企业级的功能插件等

软件包格式:
软件包管理器特有格式
rpm包,.exe格式等
通用二进制格式(类似绿色版解压即可使用)
源程序

RHEL 5.8 (64bit)
mysql,mysql-server

MySQL的官方RPM包:

LAMP:
MySQL源码包
通用二进制格式

mysql监听 TCP/3306端口
运行mysql进程的用户和组为mysql用户和组

RDBMS:
数据文件默认存储路径:/var/lib/mysql 建议创建单独存储位置

安装mysql:
yum -y install mysql-server
初始化:
为了创建元数据的数据库,mysql的元数据库就叫mysql,存储mysql初始时的内容
启动mysql数据库:
service mysqld start
安装完成登录mysql服务器:
mysql命令就能直接登录
-u username 默认root
-p PASSWORD 默认为空
-h MYSQL_SERVER 默认本机
-h 127.0.0.1 如果连接本机mysql,意味着不需要通过网络连接,这种方式会比网络连接快很多
linux:socket方式连接
windows:memory方式连接

样例:mysql -uroot -p -h localhost或172.16.100.1
输入密码,为空则直接敲回车
用户:USERNAME@HOST

mysql客户端:
交互式模式
批处理模式
执行mysql脚本
交互式模式中的命令类型:
客户端命令:\命令
\h 可以获取帮助
服务器端命令:
都必须使用语句结束符,默认是分号;

SQL接口:
Oracle,PL/SQL
SQL Server,T-SQL
MySQL

MySQL使用:
show databases; #查询mysql中是库
默认mysql有3个库:test,mysql,information_schema
在/var/lib/mysql目录中存在test,mysql目录,但没有information_schema,因为这个库存在内存中
也可以在/var/lib/mysql目录创建新的目录文件,在使用show databases; 查看可以看到新建的库

关系数据库对象:


索引
视图
约束
存储过程
存储函数
触发器
游标
用户

权限
事务

表:
行,列
表:实体
行:row
列:field,column

字段名称,数据类型,类型修饰(限制),
字符
CHAR(n) 定长的CHAR,最多256个字符
VARCHAR(n) 可变长度的CHAR,最多65536个字符两个字节
BINARY(n) 区分大小写的字符,二进制方式存储
VARBINARY(n) 不区分大小写的字符
TEXT(n)
BLOB(n) 二进制的大对象
数值
精确数值
整型
TINYINT 1字节
SMALLINT 2字节
MEDIUMINT 3字节
INT 4字节
BIGINT 8字节
修饰符:UNSIGNED,无符号,表示只有正数和0
NOT NULL:不允许为空
十进制
DECIMAL
近似数值
浮点型
FLOAT 单晶
DOUBLE 双晶
日期时间:
DATE
TIME
DATETIME
STAMP 时间戳
布尔
内置:ENUM,SET

MYSQL命令:mysql中命令不区分大小写
DDL:
CREATE
ALTER
DROP
DML:
INSERT
UPDATE
DELETE
DCL:
GRANT
REVOKE
获取帮助:
help CREATE TABLE; 获取跟CREATE TABLE相关的命令帮助
查看库:
SHOW DATABASES;
查看表:
SHOW TABLES FROM db_name;
查看表结构:
DESC tb_name;

创建数据库:
CREATE DATABASE db_name;
CREATE DATABASE IF NOT EXISTS db_name; 如果不存在则创建
删除数据库;
DROP DATABASE db_name;
DROP DATABASE [IF EXISTS] db_name; 存在则删除库
创建表:
USE db_name; 指定创建表存放的库
CREATE TABLE tb_name(col1,col2,...);
例:CREATE TABLE students(Name CHAR(20) NOT NULL,Age TINYINT UNSIGNED, Gender CHAR(1) NOT NULL);
删除表:
DROP TABLE tb_name [IF EXISTS]; 不可逆,存在则删除表
修改表:
ALTER TABLE tb_name
MODIFY:修改某个字段,更改字段属性
CHANGE:改变某个字段,改字段本身
ADD:添加字段
DROP:删除字段
例:ALTER TABLE students ADD course VARCHAR(100); 在students表中添加了course字段字符长度100
DESC students; 查看表结构就多出了course字段信息
ALTER TABLE students CHANGE course Course VARCHAR(100) AFTER Name; 将原来的course改为Course,并将其放在Name字段的后面
ALTER TABLE students DROP Course; 删除某个字段

DML:
INSERT INTO tb_name (col1,col2,...) VALUES|VALUE ('STRING',NUM,...); #插入一组数据
INSERT INTO tb_name (col1,col2,...) VALUES|VALUE ('STRING',NUM,...),('STRING',NUM,...); #插入多组数据
例:INSERT INTO students (Name,Gender) VALUE ('LingHuchong','M'),('XiaoLongnv','F');
SELECT * FROM students; #查看students表内容
INSERT INTO students (‘XiaoXiangzi’,'HaMagong',57,'M'); # 不指定字段,直接按照表字段格式插入键值
UPDATE tb_name SET clumn=value WHERE
例:UPDATE students SET Course='Pixiejianfa'; # 如果不加where条件,则会将Course字段全部改为Pixiejianfa
UPDATE students SET Course='Hamagong' WHERE Name='Xiaoxiangzi';
DELETE FROM tb_name WHERE CONDITION; # 删除表中符合条件的行
例:DELETE FROM students WHERE Course='Pixiejianfa'; # 删除students表中Course是Pixiejianfa的行
查询:
SELECT 字段 FROM tb_name WHERE CONDITION;
*:表示所有字段
WHERE:没有条件表示显示所有行
创建用户:
CREATE USER 'USERNAME'@'HOST' [IDENTIFIED BY 'PASSWORD'];
例:CREATE USER 'jerry'@'%' IDENTIFIED BY 'jerry'; # 创建jerry用户针对所有主机并设置密码为jerry
SHOW GRANTS FOR 'jerry'@'%'; # 查看jerry用户权限
HOST:
IP;
HOSTNAME;
NETWORK;
通配符; 通配符要使用''引起来
_:匹配任意单个字符,172.16.0._
%:匹配任意字符;
删除用户:
DROP USER 'USERNAME'@'HOST';

选择:指定以某字段作为搜索码,做逻辑比较,筛选符合条件的行;选择针对行;
WHERE指定选择条件
投影:投影针对列
SELECT Name,Course FROM students; # 只显示Name和Course字段列的内容
SELECT Name,Course FROM students WHERE Gender='M'; # 显示Name和Course字段中Gender为M的内容

DCL:
增加授权:
GRANT pri1,pri2,... ON DB_NAME.TB_NAME TO 'USERNAME'@'HOST' [IDENTIFIED BY 'PASSWORD'];
删除授权:
REVOKE pri1,pri2,... ON DB_NAME.TB_NAME FROM 'USERNAME'@'HOST';

所有权限:
ALL PRIVILEGES
例:GRANT ALL PRIVILEGES ON mydb.* TO 'jerry'@'%'; # 给jerry用户增加所有权限

对于mysql而言,localhost 和127.0.0.1是不同host登录方式,用户列为空的为匿名用户。
设定密码:
1、SET PASSWORD FOR 'USERNAME'@'HOST'=PASSWORD('password');
FLUSH PRIVILEGES; 每次更改需要重读授权表
2、# mysqladmin -uUSERNAME -hHOST -p password 'password' #password为老密码'password'为新密码
3、直接改mysql库中user表内的密码列对应内容,在对应用户的密码列插入一行密码即可,比较复杂不常用
方法:
mysql> UPDATE user SET Password=PASSWORD('password') WHERE USER='root' AND Host='127.0.0.1';
mysql> FLUSH PRIVILEGES;

授权远程访问:
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'172.16.%.%' IDENTIFIED BY 'redhat';
mysql> FLUSH PRIVILEGES;

创建LAMP平台

图形客户端:
1、phpMyAdmin(常用)
2、Workbench,mysql官方提供
3、MySQL Front
4、NaVicat for MySQL
5、Toad

PHP与mysql相连的程序安装:
yum install php53_mysql 安装php连接mysql的驱动程序

php连接mysql并获取数据测试代码:
<?php
$conn=mysql_connect('localhost','root','123456');

if (!$conn)
{
die('Could not connect: ' . mysql_error());
}

mysql_select_db("mydb",$conn);

$result = mysql_query("SELECT * FROM tb1");

while($row - mmysql_fetch_array($result))
(
echo $row['Name'] . " " . $row['Age'];
echo "<br />";
)

mysql_close();
?>

简单的写法:
<title>A</title>
<hl>a.org</hl>
<?php
$conn=mysql_connect('localhost','root','redhat');
if ($conn)
echo "Success...";
else
echo "Failure...";
?>

LAMP:
phpMyAdmin
get phpMyAdmin-3.4.3.2-all-languages.tar.bz2 下载包
tar xf phpMyAdmin-3.4.3.2-all-languages.tar.bz2 解压压缩文件
mv phpMyAdmin-3.4.3.2-all-languages pma 改个简单的名字
IE访问
www.a.org/pma 即可打开phpMyAdmin页面
使用mysql的登录密码进行登录

安装php扩展功能
php53-mcrypt-5.3.3-1.el5.i386.rpm
php53-xcache-1.3.2-1.el5_0.wing.i686.rpm 加速php执行效率

论坛:
discuz 免费开源,赚钱要向对方付费
phpwind 阿里巴巴收购
phpbb

PHP页面处理过程及优化架构:
PHP:脚本编程语言,php解释器
WebApp:面向对象的特性
Zend:
第一段:词法分析、语法分析、编译未Opcode(操作码);
opcode放置于内存中关机就会清除
第二段:执行opcode;

PHP 缓存器:将文件读至缓存器中
APC
eAccelerator
XCache

PHP解释器-->MySQL,如何交互?
bash:a.sh
php53-mysql

httpd+php:
CGI:服务进程,可以将httpd内需要处理的php动态传输至php进行处理,完成后返回httpd进程
Module:装载相关模块进行交互
FastCGI/FPM:php单独进程通过套接字方式处理httpd传输过来的php动态请求

动态内容的静态化:
将冬天访问请求结果缓存至静态服务器,同样访问请求进来直接从静态服务器反馈即可。无需再进行动态处理。
淘宝有专门部门将动态内容静态化,处理能力达到全站的百分之97的动态内容都可以静态化。

编译安装LAMP之httpd-2.4.4
Apache:ASF(apache 软件基金会),httpd,tomcat,cloudware
httpd:2.4.4
php:5.4.13
MySQL:5.6.10(rpm,通用二进制,源码)

安装前确保未安装过RPM包等相关安装
安装依赖关系:httpd-->MySQL-->PHP-->XCache

httpd:
apr:Apache Portable Runtime 针对不同版本的操作系统安装的httpd程序相互兼容的插件
rpm -q apr 检查安装
rpm -q apr-util util就是工具组件,apr是一个库,而util是这个库的命令工具组件

rpm包二进制格式文件存放位置:
rpm包:/bin,/sbin,/usr/bin,/usr/sbin
库文件:/lib,/usr/lib
配置文件:/etc
帮助文件:/usr/share/{doc,man}

编译安装:
/usr/local
二进制通用:bin,sbin
库:lib
配置:etc
帮助:man
二进制安装卸载:直接删除安装后的目录即可
/usr/local/apr/
bin,sbin,lib,includes,etc,share/man

编译安装:
先安装开发环境,确保"Development Tools"和"Development Librarides"均已安装
yum grouplist 查看安装组件
yum groupinstall "Development Librarides"
安装apr:
下载源程序:apr和apr-util包
安装次序:apr-->apr-util-->httpd--
安装apr:
hwclock同步时间为硬件时间
tar xf apr-1.4.6.tar.bz2 解压
cd arp-1.4.6
./configure --help|less 查看编译帮助,因为默认值均已满足需求因此不用指定更多编译内容
./configure --prefix=/usr/local/apr 指定安装目录直接安装
make && make install
apr-util安装
tar xf apr-util-1.4.1.tar.bz2
cd arp-util-1.4.1
./configure --perfix=/usr/local/apr-uril --with-arp=/usr/local/apr
make && make install
安装httpd,MPM:prefork,worker,event
2.4以后版本默认安装模式为event模式,之前为prefork
tar xf httpd-2.4.4.tar.bz2
cd httpd-2.4.4
./configure --prefix=/usr/local/apache --sysconfigdir=/etc/httpd --enabled-so --enabled-rewrite --enabled-ssl --enabled-cgi --enabled-cgid --enabled-modules=most --enabled-mods-shared=most --enabled-mpms-shared=all --with-mpms=event --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util
可能会报错信息:
未安装PCRE模块
yum -y install pcre-devel 安装
再次编译成功
make && make install

httpd 2.4新特性:
1、MPM可于运行时装载;
--enable-mpms-shared=all --with-mpm=event
2、Event MPM
3、异步读写
4、在每模块及每目录上指定日志级别
5、每请求配置:<If>,<ElseIf>,<Else>;
6、增强的表达式分析器;
7、毫秒级的KeepAlive Timeout;
8、基于域名的虚拟主机不再需要NameVirtualHost指令;
9、降低了内存占用;
10、支持在配置文件中使用自定义变量;

新增加的模块:
mod_proxy_fcgi
mod_proxy_scgi
mod_proxy_express
mod_remoteip
mod_session
mod_ratelimit
mod_request
等等;

对于基于IP的访问控制
2.2:
Order allow,deny
allow from all

2.4:
使用Require user
Require user USERNAME 允许某用户访问
not user USERNAME 不允许某用户访问
Require group GROUPNAME
Require ip IPADDR
IP
NETWORK/NETMASK
NETWORK/LENGTH
NET
172.16.0.0/255.255.0.0 = 172.16.0.0/16 = 172.16
Require host HOSTNAME
允许所有主机访问:
Require all granted
拒绝所有主机访问:
Require all deny

编译安装LAMP之MySQL-5.5.28(通用二进制格式)
tar xf mysql-5.5.28-linux2.6-i686.tar.gz -C /usr/local
cd /usr/local
ln -sv mysql-5.5.28-linux2.6-i686 mysql 做链接文件到同目录下的mysql,不要mv更改原始的源码包名
cd mysql
useradd -r mysql #-r表示创建系统用户不可删除的,与group一起创建
也可以手动创建
groupadd -r -g 306 mysql
useradd -g 306 -r -u 306 mysql
id mysql
安装过程可以通过INSTALL-BINARY文件进行解读
chown -R mysql.mysql /usr/local/mysql/*
ls scripts/mysql_install_db 此脚本是mysql初始化脚本,需手动还行 --help可以查看多个选项的解释
指定一个新的数据目录
pvcreate /dev/sda5
vgcreate myvg /dev/sda5
lvcreate -n mydata -L 5G myvg
mke2fs -j /dev/myvg/mydata
mkdir /mydata
vi /etc/fstab
/dev/myvg/mydata /mydata ext3 defaults 0 0
mount -a
mount 检查挂载
mkdir /mydata/data
chown -R mysql.mysql /mydata/data/
chmod o-rx /mydata/data/
初始化
scripts/mysql_install_db --user=mysql --datadir=/mydata/data/
属主改回root用户
chown -R root /usr/local/mysql/*
ls suport-files/mysql.server 目录下有启动脚本
cp suport-files/mysql.server /etc/init.d/mysqld 复制脚本至自动启动目录
chkconfig --add mysqld
chkconfig --list mysqld
创建mysql配置文件:
MySQL:/etc/my.conf
配置文件格式:
[mysql] 客户端用
配置参数内容
[mysqld] 服务端用
配置参数内容
[client] 对所有客户端都生效
配置参数内容

mysql启动时查找配置文件过程,依次如下:
/etc/my.cnf --> /etc/mysql/my.cnf --> $BASEDIR/my.cnf --> $DATADIR/my.cnf --> ~/.my.cnf

复制配置文件:
ls suport-files/mysql.server # my-small.cnf(小规模)\my-medium.cnf(中级别)\my-large.cnf(大型)\my-huge.cnf(巨大型)
还有特殊的my-innodb-heavy-4G.cnf mysql的一种存储引擎
查看各配置文件中内容,便知是根据实际物理资源量来评估承载数据量的配置文件
cp suport-files/my-large.conf /etc/my.cnf
vim /etc/my.cnf
查找内容
thread_concurrency = 8 线程并发量,最多启动多少mysql线程,改为你的CPU个数*2的结果
添加数据目录
datadir = /mydata/data
启动mysql进程
service mysqld start
vim /etc/profile.d/mysql.sh
exprot PATH=$PATH:/usr/local/mysql/bin
保存退出
重新登录即可
MySQL服务器维护了两类变量:
服务器变量:
定义MySQL服务器运行特性
SHOW GLOBAL VARIABLES
SHOW GLOBAL VARIABLES LIKE 'STRING'; 特定变量查看 调优mysql主要看内容
状态变量:
保存了MySQL服务器运行统计数据
SHOW GLOBAL STATUS
SHOW GLOBAL STATUS LIKE 'STRING'; 特定变量查看 调优后是否得到提升查看内容

MySQL通配符:
_:任意单个字符
%:任意长度的任意字符

SELECT VERSION(); 显示当前数据库版本号
SELECT DATABASE(); 显示当前数据库
SELECT USER(); 显示登录用户

系统帮助文件添加mysql帮助内容
vim /etc/man.config
添加:
MANPATH /usr/local/mysql/man

输出库文件:
vim /etc/ld.so.conf.d/mysql.conf
/usr/local/mysql/lib
保存退出
ldconfig -v 让系统重新读取库文件,重新读取到缓存
ls -l /etc/ld.so.cache 缓存文件位置

输出头文件:
ln -sv /usr/local/mysql/include /usr/include/mysql
ls /usr/include/mysql 能看到一些头文件

编译安装LAMP之php-5.4.13、xcache-2.0及使用ab命令实现压力测试
tar xf php-5.4.13.tar.bz2
cd php-5.4.13
./configure --prefix=/usr/local/php --with-mysql=/usr/local/mysql --with-openssl --with-mysqli=/usr/local/mysql/bin/mysql_config --enable-mbstring --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml --enable-sockets --with-apxs2=/usr/local/apache/bin/apxs --with-mcrypt --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-bz2 --enable-maintainer-zts

支持FastCGI模式可将
--with-apxs2=/usr/local/apache/bin/apxs 更改为 --enable-fpm即可


说明:
1、这里为了支持apache的worker或event这两个MPM,编译时使用了--enable-maintainer-zts选项
2、如果使用PHP5.3以上版本,为了链接MySQL数据库,可以指定mysqlnd,这样在本机就不需要先安装MySQL或MySQL开发包了。mysql从php5.3开始可用,可以编译时绑定到它(而不用和具体的MySQL客户端库绑定形成依赖),但从PHP 5.4开始它就默认设置了。
# ./configure --with-mysql=mysqlnd --with-pdo-mysql=mysqlnd --with-mysqli=mysqlnd

报错:
mcrypt.h没有相关的头文件依赖,不使用加密功能可不加此参数
也可安装依赖包
mhash、mhash-devel、libmcrypt、libmcrypt-devel这4个包即可

找rpm安装依赖包可以到rpmfind.net网站中查找下载

make && make install

cp php.ini-production /etc/php.ini cp配置文件到默认目录
vim /etc/php.ini
vim /etc/httpd/httpd.conf
查找AddType字样,添加apache对php页面的处理
在后面添加一行:
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
再查找DirectoryIndex index.html
修改为DirectoryIndex index.php index.html

php支持扩展功能:
xcache
xcache加速
tar xf xcache-2.0.0.tar.bz2
cd xcache-2.0.0
/usr/local/php/bin/phpize #准备好的php扩展功能准备编译,编译任何php相关扩展功能,都需要先执行此命令,识别扩展
./configure --enable-xcache --with-php-config=/usr/local/php/bin/php-config
make && make install
加载xcache到php配置中
1、可以将xcache解压目录下的xcache.ini文件内容加载到php.ini配置文件中
2、mkdir /etc/php.d 创建配置文件目录
cp xcache.ini /etc/php.d/
vim /etc/php.d/xcache.ini
找到zend_extension = 路径 将xcache安装的路径贴入 /usr/local/php/lib/extensions/no-debug-zts-20100525/xcache.so
将zend_extension_ts = 这行注销掉,在行首输入;即可

gc=垃圾回收器
更改xcache配置后需要重启httpd生效

启用虚拟主机:
注释掉中心主机
vim /etc/httpd/httpd.conf
查找DcoumentRoot行 注销掉#
然后找到
#Virtual hosts
Include /etc/httpd/extra/httpd-vhosts.conf
将虚拟主机单独配置到此配置文件
再查找到LoadModule中的mod_log_config.so是否启用
保存退出
编辑虚拟主机配置文件
vim /etc/httpd/extra/httpd-vhosts.conf

样例:
<VitrualHost *:80>
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot "/usr/local/apache/docs/dummy-host.example.com"
ServerName dummy-host.example.com
ServerAlias www.dummy-host.example.com"
ErrorLog "logs/dummy-host.example.com-error_log"
CustomLog "logs/dummy-host.example.com-access_log" common
</VirtualHost>

自己编辑主机
<VitrualHost *:80>
ServerName www.a.org
<Directory "/www/a.org">
Options none
AllowOverride none
Require all granted
</Directory>
DocumentRoot "/www/a.org"
ErrorLog "/var/log/httpd/a.org-error_log"
CustomLog "/var/log/httpd/a.org-access_log" combined
</VirtualHost>

<VitrualHost *:80>
ServerName www.b.net
<Directory "/www/b.net">
Options none
AllowOverride none
Require all granted
</Directory>
DocumentRoot "/www/b.net"
ErrorLog "/var/log/httpd/b.net-error_log"
CustomLog "/var/log/httpd/b.net-access_log" common
</VirtualHost>
保存退出
mkdir /www/{a.org,b.net} -pv
mkdir /var/log/httpd
httpd -t #检查语法

web压力测试
cd /usr/local/apache
ab命令:apache benchmark,apache压力测试工具
ab
-c concurrency #:并发量,一次性发起的请求数量,默认为1;
-i :测试时使用HEAD方法,默认为GET;
-k :启用HTTP长连接请求方式;
-n requests #:发起的模拟请求个数,默认为1个,请求数要大于等于并发连接数;
-q :静默模式,在请求数大于150个时不输出请求完成百分比;
-r :忽略错误
例如:ab -c 10 -n 100 http://www.a.org/index.html
结果指标:
Time taken for tests : # seconds 从第一个请求连接简历到收到最后一个请求的相应报文结束所经历的时长;
Complete requests :成功的请求数;
Total transferred : 100次请求所有的报文大小
HTML transferred : HTML文件请求的报文大小
Requests per second : 每秒钟处理的请求数量
Time per request : 每个请求花费时长,此时长为所有请求全部完成后的平均时长,10个并发全部完成的时间
Time per request : 单个请求花费的时长,应该是上面的十分之一
Transfer rate : 传输速率,大概每秒钟传输的字节

Linux操作系统限定每个进程不允许打开1024个文件
ulimit -n 10000 重新设定每个进程打开文件为10000个

测试动态站点
tar xf phpMyAdmin-3.5.1-all-languages.tar.bz2 -C /www/b.net
cd /www/b.net
mv phpMyAdmin-3.5.1-all-languages/ pma
cd pma
cp config.sample.inc.php config.inc.php
vim config.inc.php
使用openssl生成一段随机码
openssl rand -base64 10
将生成的==前面的字符串拷贝出来
放置于config.inc.php配置文件中的xxxx中
$cfg['blowfish_secret'] = 'xxxxxx';
保存退出
访问页面进行mysql客户端登录

再使用ab进行动态页面测试
ab -c 100 -n 1000 http://www.b.net/pma/index.php

压力测试工具:
ab
http_load
webbench
siege

启用https功能
vim /etc/httpd/httpd.conf
找到LoadModule
找到ssl_module_modules一行取消注释

再找到Include /etc/httpd/extra/httpd-ssl.conf 取消注释启用
保存退出

vim /etc/httpd/extra/httpd-ssl.conf
更改
DocumentRoot "/www/a.org"
ServerName www.aorg
ErrorLog "/var/log/httpd/a.org-error_log
TransferLog "/var/log/httpd/a.org-access_log

私钥和公钥内容指定
保存退出
从起web服务

编译安装LAMP之配置httpd以FastCGI方式与php整合
httpd+php结合方式:
cgi
module
fastcfi(fpm)
httpd:
fastcgi模块
2.4,fcgi
--enable-module=most

通用二进制格式包安装mysql5.6版本:
tar xf mysql-5.6.10-linux-glibc2.5-i686.tar.gz -C /usr/local
cd /usr/local
ln -sv mysql-5.6.10-linux-glibc2.5-i686 mysql
cd mysql
chown -R mysql.mysql .
scripts/mysql)instal_db --user=mysql --datadir=/mydata/data
cd support-files/
cp mysql.server /etc/init.d/mysqld 复制启动脚本到自启动目录
chkconfig --add mysqld
chkconfig --list mysqld
cp my-default.cnf /etc/my.cnf 拷贝配置文件
vim /etc/my.cnf
找到datadir
datadir = /mydata/data
保存退出
chown -R root .
service mysqld start
vim /etc/profile.d/mysql.sh 输出mysql目录
export PATH=$PATH:/usr/local/mysql/bin
保存退出

编译安装php5.4.13
tar xf php-5.4.13.tar.bz2
cd php-5.4.13
./configure --prefix=/usr/local/php --with-mysql=/usr/local/mysql --with-openssl --with-mysqli=/usr/local/mysql/bin/mysql_config --enable-mbstring --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml --enable-sockets --enable-fpm --with-mcrypt --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-bz2

此版本支持FastCGI模式可将
--with-apxs2=/usr/local/apache/bin/apxs 更改为 --enable-fpm即可

make && make install
cp php.ini-production /etc/php.ini
为php-fmp提供Sysv init脚本,并将其添加至服务列表:
cp sapi/fpm/init.d.php-fpm /etc/rc.d/init.d/php-fpm
chmod +x /etc/rc.d/init.d/php-fpm
chkconfig --add php-fpm
chkconfig php-fpm on

为php-fpm提供配置文件:
cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf

编辑php-fpm的配置文件:
vim /usr/local/php/etc/php-fpm.conf
配置fpm的相关选项为你所需要的值,并启用pid文件(如下最后一行);
pm.max_children = 50 # 最多有多少子进程
pm.start_servers = 5 # 启动的空闲进程数
pm.min_spare_servers = 2 # 最小的空闲进程数
pm.max_spare_servers = 8 # 最大的空闲进程数
pid = /usr/local/php/var/run/php-fpm.pid # 定义pid存放文件位置

接下来就可以启动php-fpm了:
service php-fpm start

启动监听在:
127.0.0.1:9000端口上

配置httpd-2.4.4
1、启用httpd的相关模块
在apache httpd 2.4以后的版本已经专门有一个模块针对FastCGI的实现,此模块未mod_proxy_fcgi.so,它其实是作为mod_proxy.so模块的扩充,因此,这两个模块都要加载
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so

2、配置虚拟主机支持使用fcgi
在响应的虚拟主机中添加类似如下两行:
ProxyRequests off # 关闭正向代理功能
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/PATH/TO/POCUMENT_ROOT/$1 # 所有访问php的全部解析到对应的fcgi://127.0.0.1:9000地址去

例如:
<VirtualHost *:80>
DocumentRoot "/www/magedu.com"
ServerName magedu.com
ServerAlias www.magedu.com

ProxyRequests off
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/PATH/TO/POCUMENT_ROOT/$1

<Directory "/www/magedu.com">
Options none
AllowOverride none
Require all granted
</Driectory>
</VirtualHost>

邮件服务系列之基础原理
Mail Server:

SMTP:Simple Mail Transfer Protocol 简单邮件传输协议 25/tcp
ESMTP:Extended 检测身份认证
POP3:Post Office Protocol 邮局协议
IMAP4:Internet Mail Access Protocol 互联网邮件访问协议
早期:
UUCP:Uinx to Unix Copy
Unix主机复制文件的协议
SMTP:就是文件传输协议,实现传输路由功能

邮件传输:MT
邮件投递:MD
邮件用户:MU

MUA:Mail User Agent 邮件用户代理,就是邮件客户端软件
Outlook Express,Outlook
Foxmail
Thunderbird
Evolution
mutt(纯文本界面)

MTA:Mail Transfer Agent 邮件传输代理,SMTP服务器
SendMail,UUCP
单体结构,SUID,配置文件语法(m4编写)
qmail
性能非常良好,但作者是个数学家玩了两三年就放弃此项目,一个PC机可投递20封每秒
postfix
邮件新贵,模块化设计,安全,与SendMail兼容性良好,投递效率很高
exim
配置语法简单,使用简易
Exchange(Windows,异步消息协作平台)
必须与AD整合,可同步日历

SASL:v2版本使用较多
cyrus-sasl,认证框架,但不提供认证服务,例如:好比围墙,但不提供围墙门锁进出的过程
courier,可提供MTA,MDA,MRA服务,但提供不如postfix好,因此只选用此软件的courier-authlib功能

MDA:Mail Deliyery Agent 邮件投递代理
SendMail:procmail负责投递的
maildrop:专业的邮件投递代理,自带垃圾邮件过滤功能

MRA:Mail Retrival Agent,邮件检索或取回代理,此时使用的POP3、imap4协议
cyrus-imap
dovecot(鸽子笼)

WebMail:
Openwebmail,使用perl语言研发
squirrelmail(小松鼠mail),使用PHP语言研发
Extmail(Extman),国产开源
EMOS:定制的CentOS,直接安装好之后即成为mail服务器

发邮件为SMTP协议,收邮件为POP3或IMAP协议

LMTP:local 本地邮件传输协议

Open Relay:开放式中继

邮件服务要借助第三方认证工具:
SASL:Simple Authintication Secure Layer,简单认证安全层

WebMail

LDAP:Lightweight Directory Access Protocol,轻量级目录访问协议
读快写慢,一次写入多次读取的场景适合使用。大数量用户认证会使用例如网易邮箱等
MySQL:写比LDAP快一个量级,而读要比LDAP慢一个量级。

虚拟用户:仅用于访问某个服务的数字标识;
用户:字符串,凭证

POP3可直接访问MySQL或LDAP服务器进行验证;
SMTP需要借助SASL完成用户验证;SASL还需要通过 工具去连接MySQL数据库进行验证;
垃圾邮件过滤器,进行内容检索。


邮件服务系列之编译安装Postfix-2.10.0
发邮件:Postfix + SASL(courier-authlib) + MySQL
收邮件:Dovecot + MySQL
Webmail:Extmail + Extman + httpd

Postfix:rpm包安装不支持基于SASL对虚拟用户的认证,因此系统自带rpm包不符合需要,需自己编译安装
红帽6版本以后默认安装的都是Postfix,之前都是SendMail
卸载SendMail
service sendmail stop
chkconfig sendmail off
yum list all|grep sendmail
rpm -e sendmail --nodeps 忽略依赖关系卸载

安装准备工作:
安装器说明:邮件服务依赖于DNS服务,请事先确认您的DNS服务已经为邮件应用配置完成。

安装所需包如下:
httpd,mysql,mysql-server,mysql-devel,openssl-devel,dovecot,perl-DBD-MySQL,tcl,tcl-devel,libart-lgpl,libart-lgpl-devel,libtool-ltdl,libtool-ltdl-devel,expect

安装Postfix
先安装MySQL(步骤忽略)
service mysqld start
chkconfig mysqld on
mysqladmin -uroot password 'your_passwrod'
启动saslauthd服务,并将其加入到自动启动队列
service saslauthd start
chkconfig saslauthd on
下载Postfix,在官方www.postfix.org下载,找到download中Souce code下载
groupadd -g 2525 postfix
useradd -g postfix -u 2525 -s /sbin/nologin -M postfix
groupadd -g 2526 postdrop
useradd -g postdrop -u 2526 -s /sbin/nologin -M postdrop 邮件投递用户和组
tar zxvf postfix-2.10.0.tar.gz
cd postfix-2.10.0
less INSTALL 查看安装文件
make makefiles 'CCARGS=-DHAS_MYSQL -I/usr/local/mysql/include -DUSE_SASL_AUTH -DUSE_CYRUS_SASL -I/usr/include/sasl -DUSE_TLS' 'AUXLIBS=-L/usr/local/mysql/lib -lmysqlclient -lz -lm -L/usr/lib/sasl2 -lsasl2 -lssl -lcrypto'
make
make install

按照以下的提示输入相关的路径([]号中的是缺失值,"]"后的是输入值,省略的标识采用默认值

install_root:[/]/
tempdir:[/root/postfix-2.10.0] /tmp/postfix
config_firectory:[/etc/postfix] /etc/postfix
.....
均可使用默认值

生成别名二进制文件:
newaliases

进行一些基本配置,测试启动postfix并进行发信
postfix模块化:
master:/etc/postfix/master.cf 核心模块,主进程
mail:/etc/postfix/main.cf 邮件实现功能的配置文件
格式:参数 = 值 # 参数必须写在行的绝对行首;以空白开头的行被认为是上一行的延续
postconf:配置postfix
-d:显示默认的配置
-n:修改了的配置
-m:显示所支持的查找表类型
-A:显示客户端支持的SASL插件类型
-a:显示服务器端支持的SASL插件类型
-e PARMATER=VALUE:更改某参数配置信息,并保持至main.cf文件中

vim /etc/postfix/main.cf
修改以下几项为您需要的配置
myhostname = mail.magedu.com # 当前所配置邮件服务器的主机名称
myorigin = magedu.com # 邮件地址伪装或补全
mydomain = magedu.com # 当前主机所在域
mydestination = $myhostname,localhost.$mydomain,localhost,$mydomain # 定义本地所有邮件目标收件服务器,也就是除此之外的需要中继转发
mynetworks = 192.168.1.9/24,127.0.0.0/8 # 给来自哪些网段的邮件中继转发

说明:
myorigin 参数用来知名发件人所在的域名,即做发件地址伪装;
mydestination 参数指定postfix接收邮件时收件人的域名,即您的postfix系统要接受到哪个域名的邮件
myhostname 参数指定运行postfix邮件系统的主机的主机名,默认情况下,其值被设定为本机器名
mydomain 参数指定您的域名,默认情况下,postfix将myhostname的第一部分删除而作为mydomain的值
mynetworks 参数指定你所在的网络的网络地址,postfix系统根据其值来区别用户是远程的还是本地的,如果是本地网络用户则允许其访问;
inet_interfaces 参数指定postfix系统监听的网络接口;

注意:
1、在postfix的配置文件中,参数行和注释行是不能出在同一行中的;
2、任何一个参数的值都不需要加引号,否则,引号将会被当作参数值的一部分来使用;
3、每个修改参数及其值后执行postfix reload即可令其生效;但若修改了inet_interface,则需重新启动postfix
4、如果一个参数的值有多个,可以将它们放在不同的行中,只需要在其后的每个行前多置一个空格即可;postfix会把第一个字符为空格或tab的文件行视为上一行的延续;

为postfix提供SysV服务脚本/etc/rc.d/init.d/postfix,
#!/bin/bash
#
# postfix Postfix Mail Transfer Agent
#
# chkconfig:2345 80 30
# description:Postfix is a Mail Transport Agent, which is the program \
that moves mail from one machine to another
# processname: master
# pidfile: /var/spool/postfix/pid/master.pid
# config: /etc/postfix/main.cf
# config: /etc/postfix/master.cf

# Source function library
. /etc/rc.d/init.d/function

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ $NETWORKING = "no" ] && exit 3

[ -x /usr/sbin/postfix ] || exit 4
[ -d /etc/postfix ] || exit 5
[ -d /var/spool/postfix ] || exit 6

RETVAL=0
prog="postfix"

start() {
# Start daemons.
echo -n $"Starting postfix:"
/usr/bin/newaliases >/dev/null 2>&1
/usr/sbin/postfix start 2>/dev/null 1>&2 && success || failure $"$prog start"
RETVAL=$?
[ $RETVAL -eq 0 ] && touch /var/locak/subsys/postfix
echo
return $RETVAL
}

stop() {
# Stop daemons.
echo -n $"Shutting down postfix:"
/usr/sbin/postfix stop 2>/dev/null 1>&2 && success || failure $"$prog stop"
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f /var/locak/subsys/postfix
echo
return $RETVAL
}

reload() {
# Reload daemons.
echo -n $"Reloading postfix:"
/usr/sbin/postfix reload 2>/dev/null 1>&2 && success || failure $"$prog reload"
RETVAL=$?
echo
return $RETVAL
}

abort() {
/usr/sbin/postfix abort 2>/dev/null 1>&2 && success || failure $"$prog abort"
return $?
}

flush() {
/usr/sbin/postfix flush 2>/dev/null 1>&2 && success || failure $"$prog flush"
return $?
}

check() {
/usr/sbin/postfix check 2>/dev/null 1>&2 && success || failure $"$prog check"
return $?
}

restart() {
stop
start
}

# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
reload)
reload
;;
abort)
abort
;;
flush)
flush
;;
check)
check
;;
status)
status master
;;
condrestart)
[ -f /var/lock/subsys/postfix ] && restart || ;
;;
*)
echo $"Usage:$0 {start|stop|restart|reload|abort|flush|check|status|condrestart}"
exit 1
esac

exit $?

#END

为此脚本赋予执行权限:
chmod +x /etc/rc.d/init.d/postfix
设置开机启动:
chkconfig --add postfix
chkconfig postfix on
service postfix restart


telnet localhost 25
邮件与web服务一样会返回状态码
SMTP状态码:
1开头为纯信息
2开头为正确码
3开头web为重定向,但邮件为信息处理尚未完毕还需要进一步操作
4开头web为客户端错误,邮件为暂时性错误
5开头web为服务端错误,邮件为永久性错误

SMTP协议原语:
helo (smtp协议)
ehlo (esmtp协议)
mail from:root (指定发件人)
rcpt to:openstack (指定收件人)
data (邮件内容,正文)
内容
. # 结束编辑标记
quit
tail /var/log/maillog
可以查看到已发送的信息
su - openstack
使用mail命令查看新收到的邮件

alias:邮件别名,邮件服务无法直接写入/etc/aliases别名,因此需要重新定义
/etc/aliases --> hash --> /etc/aliases.db
需要使用newaliases命令散列此别名

postfix默认吧本机的IP地址所在的网段识别为本地网络,并且为之中继

邮件服务系列之Postifx常用配置
SMTP --> SMTPS 安全版
ESMTP 功能增强版
接收邮件:
POP3:邮局协议
IMAP4:互联网邮件访问协议
用户认证框架:
SASL:简单认证安全层
v1,v2
MDA:邮件投递代理
procmail,maildrop
MUA:邮件用户代理
mutt,mail
Mail Relay:邮件中继
MTA:sendmail,qmail,postfix,exim,exchange

postfix:模块化设计,master(/etc/postfix/master.cf)
(/etc/postfix/main.cf)

MX:Mail.magedu.com

配置DNS服务:
将主机名改为mail.magedu.com
改hosts和network文件
rpm -qa |grep bind # 检查是否有装bind
rpm -e bind-libs bind-utils # 卸载现有版本
yum install bind97 bind-utils
vim /etc/named.conf
找到options内容53端口号一行注销掉
重启named服务
netstat -tunlp 查看53监听
vim /etc/named.rfc1912.zones
未行添加新区域
zone "magedu.com" IN {
type master;
file "magedu.com.zone";
allow-update { none; };
allow-transfer { none; };
};

zone "100.16.172.in-addr.arpa" IN {
type master;
file "172.16.100.zone";
allow-update { none; };
allow-transfer { none; };
};

保存退出
named-checkconf # 检查语法
cd /var/named
vim magedu.com.zone
$TTL 600
@ IN SOA ns.magedu.com. admin.magedu.com. (
2013041201
2H
10M
3D
1D )
IN NS ns
IN MX 10 mail
ns IN A 172.16.100.1
mail IN A 172.16.100.1
保存退出
cp magedu.com.zone 172.16.100.zone
vim 172.16.100.zone
$TTL 600
@ IN SOA ns.magedu.com. admin.magedu.com. (
2013041201
2H
10M
3D
1D )
IN NS ns.magedu.com.
1 IN PTR ns.magedu.com.
1 IN PTR: mail.magedu.com.
保存退出

chgrp named magedu.com.zone 172.16.100.zone
chmod 640 magedu.com.zone 172.16.100.zone
service named start
checkconfig named on
dig -t MX magedu.com @172.16.100.1
dig -t A mail.magedu.com @172.16.100.1
dig -x 172.16.100.1 @172.16.100.1
继续配置邮件服务器:
cd /etc/postfix
vim main.cf
添加
mynetwork = 172.16.0.0/16, 127.0.0.0/8
找到myhostname,添加
myhostname = mail.magedu.com
找到myorigin,添加
myorigin = $mydomain
找到mydomain,添加
mydomain = magedu.com
找到mydestination,添加
mydestination = $myhostname,$mydomain,localhost,ns.$mydomain
保存退出
service postfix restart
tail /var/log/maillog
vim /etc/resolv.conf
添加
nameserver 172.16.100.1
telnet mail.magedu.com 25
helo mail.magedu.com # 创建链接
mail from:abc@abc.com # 发件人
rcpt to:obama@whitehouse.com # 收件人
data # 提示内容编写
hello # 邮件正文内容
. # 编写内容结束
quit # 退出连接
tail /var/log/maillog
禁用掉mynetwork中的172.16.0.0/16测试
rcpt to:a@b.net
提示 554 Relay access denied

使用outlook客户端接收发送邮件
邮件编码解密:base64编码
openssl base64 可解码
如:echo "abc" | openssl base64
得出编码结果

安装配置POP3接收邮件服务器:
MRA组件:
cyrus-imap,dovecot
dovecot依赖于MySQL客户端
yum install dovecot
收件协议:
pop3:110/tcp
imap4:143/tcp
以明文方式工作,后期需要添加加密方式。
dovecot支持四中协议:pop3,imap4,pops,imaps
配置文件:/etc/dovecot.conf
自带SASL认证能力
邮箱格式:
mbox:一个文件存储所有邮件,redhat默认安装的此格式;
maildir:一个文件存储一封邮件,所有邮件存储在一个目录中;

vim /etc/dovecot.conf
查找protocols,取消注释启用,将imaps和pop3s去掉
保存退出
service dovecot start
telnet收取邮件:
telnet mail.magedu.com 110
USER openstack # 用户名
PASS openstack # 密码
List # 列出邮件列表
RETR 1 # 读取第一封邮件
RETR 2 # 读取第二封邮件
quit
这样查看到的邮件内容为密文

实现postfix + SASL 用户认证:
1、启动sasl服务
启动文件:/etc/init.d/saslouthd
配置文件:/etc/sysconfig/saslauthd
vim /etc/sysconfig/saslauthd
MECH=pam改为shadow # 认证机制
saslauthd -v # 显示当前服务器saslauthd服务所支持的认证机制。
启动服务:
service saslauthd start
chkconfig saslauthd on
测试认证:
testsaslauthd -u username -p password
如:gtestsaslauthd -u openstack -p openstack
2、postconf -a # 查看是否支持sasl
反馈结果有cyrus和dovecot则表示支持
在postfix开启sasl功能
vim /etc/postfix/main.cf
添加以下内容:
#########################CYRUS-SASL#####################
broken_sasl_auth_chlients = yse # 是否开启SASL验证postfix客户端身份
smtpd_recipient_restrictrions=permit_mynetworks,permit_sasl_authenticated,reject_invalid_hostname,reject_non_fqdn_hostname,reject_unknown_sender_domain,reject_non_fqdn_sender,reject_non_fqdn_recipient,reject_unknown_recipient_domain,reject_unauth_pipelining,reject_unauth_destination
smtp_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_secutity_options = noannoymous
2.3版本之后被废弃 smtpd_sasl_application_name = stmpd
smtpd_sasl_path = smtpd
smtpd_banner = Welcome to our $myhostname ESMTP,Warning;Version not Available!
########################################################
解释:
permit_mynetworks 允许本地网络
permit_sasl_authenticated 允许sasl认证通过的账户
reject_invalid_hostname 拒绝主机名不合法的主机
reject_non_fqdn_hostname 决绝非fqdn格式的账户收发邮件
reject_unknown_sender_domain 决绝无法识别的发件人
reject_non_fqdn_sender 拒绝无fqdn解析用户
reject_non_fqdn_recipient 拒绝没有fqdn格式的收件人
reject_unknown_recipient_domain 决绝无法识别的收件人域
reject_unauth_pipelining 拒绝无法验证的管道
reject_unauth_destination 拒绝未知目标主机
SASL支持smtpd协议
vim /usr/lib/sasl2/smtpd.conf
添加一下内容:
pwcheck_method:saslouthd # 密码检查方法
mech_list:PLAIN LOGIN # 两种认证机制,OUTLOOK是基于LOGIN认证机制

让postfix重新加载配置文件:
/usr/local/postfix reload
service saslauthd restart

实现postfix基于客户端的访问控制:
postfix内置了多种反垃圾邮件的机制,其中就包括"客户端"发送邮件限制。
限定类型:IP,域名,用户等等
smtpd_client_restrictions # 限定那些人连接邮件服务器
smtpd_data_restrictions # 限定那些人可以发送data指令
smtpd_helo_restrictions # 限定哪些人可以发送helo指令
smtpd_recipient_restrictions # 限定那些人可以发送rcpt指令
smtpd_sender_restrictions # 限定哪些人可以发送mail from指令
以上是smtp会话过程的特定阶段,postfix会根据smtpd_client_restrictions参数来判别此客户端IP的访问权限;相应的,mtpd_helo_restrictions则用于根据用户的helo信息判别客户端的访问能力等

如果DATA命令之前的所有内容被接受,客户端接着就可以开始传送邮件内容了。邮件内容通常两部分组成,前半部分是标题(header),其可以由header_check过滤,后半部分是邮件正文(body),其可以由check_body过滤。这两项实现的是邮件"内容检查"。

postfix的默认配置如下:
smtpd_client_restrictions = check_client_access hash:/etc/postfix/data-access
smtpd_data_restrictions =
smtpd_end_of_data_restrictions =
smtpd_etrn_restrictions =
smtpd_helo_restrictions = check_helo_access mysql:/etc/postfix/mysql_user # 表示去此文件链接mysql库进行控制访问
smtpd_recipient_restrictions = permit_mynetworks(允许),reject_unauth_destination(拒绝)
smtpd_sender_restrictions =

这限制了只有mynetworks参数中定义的本地网络中的客户端菜能通过postfix转发邮件,其他客户端则不允许,从而关闭了开放式中继(open relay)的功能。

配置文件配置方式:
smtpd_recipient_restrictions = check_recipient_access hash:/etc/postfix/recipient,permit_mynetworks,reject_unauth_destination
postfix有多个内置的限制条件,如上面的permit_mynetworks和reject_unauth_destination,但管理员也可以使用访问表(access map)

例如:创建访问列表:/etc/postfix/access --> hash格式 --> /etc/postfix/access.db
转换二进制命令:postmap /etc/postfix/access
内容: obama@aol.com reject # 拒绝此用户访问
microsoft.com OK # 允许此域访问
访问列表也可以通过MySQL数据库来创建
来自定义限制条件,自定义访问表的条件通常使用check_client_access,check_helo_access,check_sender_access,check_recipient_access进行,他们后面通常跟上type:mapname格式的访问表类型和名称。其中,check_sender_access和check_recipient_access用来检查客户端提供的邮件地址,因此,其访问表中可以使用完整的邮件地址,如:admin@magedu.com;也可以只使用域名,如:magedu.com;还可以只有用户名的部分,如:marion@。


别名使用:
别名即当收件人为某某时均转发给某某地址
配置:
vim /etc/aliases
添加:
a@magedu.com: hadoop
tomcat: hadoop
保存退出
newaliases # 刷新别名
service postfix restart
发给tomcat的邮件即转发给了hadoop,而tomcat收不到此邮件。并且没有a@magedu.com账户也会转发给hadoop用户

注意:使用2.10.0版本增加了访问控制和SASL认证后始终无法中继转发,更换2.9.6就ok了,因此可能是2.10.0的bug问题,建议都选用次新版本进行配置使用

邮件服务系列之 postifx+sasl+dovecot及虚拟域相关概念
myorigin:发件人地址伪装
inet_interfaces:定义postfix进程监听的IP地址
127.0.0.1

dovecot

RHEL 6.3
Development Tools
Server Platform Development
Desktop Platform Development

mysql
rpm:
mysql-server
mysql-devel

postfix,sasl

httpd,openssl,openssl-devel

所有程序编译安装都需要安装其devel包,因为关联的库文件和头文件都存在与devel包中

RHEL自身提供的rpm包:
头文件:/usr/include/
库文件:/lib,/usr/lib
第三方的rpm包:
/usr/local,/opt
头文件:/usr/include,/usr
库文件:/usr/local/lib 操作系统不会主动查找
/etc/ld.so.conf.d/local.conf
/etc/ld.so.conf
添加一行 include ld.so.conf.d/*.conf
ldconfig命令

rpm包安装postfix
yum install mysql-server mysql-devel
chkconfig mysqld on
service mysqld start
tar xf postfix-2.9.6.tar.gz
cd postfix-2.9.6
make makefiles 'CCARGS=-DHAS_MYSQL -I/usr/include/mysql -DUSE_SASL_AUTH -DUSE_CYRUS_SASL -I/usr/include/sasl -DUSE_TLS' 'AUXLIBS=-L/usr/lib/mysql -lmysqlclient -lz -lm -L/usr/lib/sasl2 -lsasl2 -lssl -lcrypto'
make
make install
创建响应用户和组:
groupadd -g 2525 postfix
useradd -g postfix -u 2525 -s /sbin/nologin -M postfix
groupadd -g 2526 postdrop
useradd -g postdrop -u 2526 -s /sbin/nologin -M postdrop 邮件投递用户和组

newaliases
ls /etc/aliases.db 确保此文件生成结束
vim /etc/postfix/main.cf
修改以下几项为您需要的配置
myhostname = mail.magedu.com # 当前所配置邮件服务器的主机名称
myorigin = magedu.com # 邮件地址伪装或补全
mydomain = magedu.com # 当前主机所在域
inet_interfaces = all # 指定监听端口和范围
mydestination = $myhostname,localhost.$mydomain,localhost,$mydomain # 定义本地所有邮件目标收件服务器,也就是除此之外的需要中继转发
mynetworks = 192.168.1.9/24,127.0.0.0/8 # 给来自哪些网段的邮件中继转发
其他配置信息解释:
alias_maps = hash:/etc/aliases # 别名映射表,对应的是/etc/aliases.db
alias_database = hash:/etc/aliases # 别名映射数据库
home_mailbox = Mailbox # 投递邮箱格式类型定义
mail_spool_directory = /var/spool/mail # 用户投递邮箱存放位置定义
mailbox_command = /some/where/procmail # 邮件投递代理,如果maildrop需要在master.cf中配置
保存退出
postconf -n
service postfix start
tail /var/log/maillog # 因sendmail已启动占用了25监听端口
service sendmail stop
chkconfig sendmail off
service postfix start
tail /var/log/maillog

配置收邮件服务器:
yum install dovecot -y
vim /etc/dovecot.conf
protocols = imap imaps pop3 pop3s
保存退出
service dovecot start
chkconfig dovecot on
echod "redhat" | passwd --stdin openstack # 为openstack设定密码为redhat
测试收邮件
mutt命令:收邮件命令
mutt
-f file:file指定用户邮箱。 如:mutt -f pop://openstack@mail.magedu.com 打开后输入密码,登录后可看到邮件列表,打开邮件可查看内容,使用i键回到主界面,r为回复邮件
使用虚拟域时需要写成:mutt -f pop://openstack@mail.magedu.com@172.16.100.1,指定主机
配置认证sasl功能
cyrus-sasl
服务脚本:saslauthd
postfix --> /usr/lib/sasl2/smtpd.conf # 与postfix相关联的配置文件
内容:
pwcheck_method:saslauthd # 通知postfix需要使用sasl进行用户认证
mech_list:PLAIN LOGIN # 选用那种方式认证
配置:
vim /etc/sysconfig/saslauthd
将MECH=pam 改为 MECH=shadow
保存退出
service saslauthd start
chkconfig saslauthd on
testsaslauthd -uhadoop -phadoop # 测试
vim /usr/lib/sasl2/smtpd.conf
pwcheck_method:saslauthd
mech_list:PLAIN LOGIN
log_level:3
保存退出
service saslauthd restart
配置postfix:
vim /etc/postfix/main.cf
找到mynetworks
mynetworks = 127.0.0.0/8
文件尾部添加内容:
#########################CYRUS-SASL#####################
broken_sasl_auth_chlients = yse # 是否开启SASL验证postfix客户端身份
smtpd_recipient_restrictrions=permit_mynetworks,permit_sasl_authenticated,reject_invalid_hostname,reject_non_fqdn_hostname,reject_unknown_sender_domain,reject_non_fqdn_sender,reject_non_fqdn_recipient,reject_unknown_recipient_domain,reject_unauth_pipelining,reject_unauth_destination
smtp_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_secutity_options = noannoymous
smtpd_sasl_path = smtpd
smtpd_banner = Welcome to our $myhostname ESMTP,Warning;Version not Available!
保存退出
service postfix restart

主机概念:
中心主机:一个服务器只能提供一个站点
虚拟主机:可提供多个站点

邮件虚拟域:
一台服务器为多个域收发邮件
mydestination = 指定多个域
使用虚拟域就需要注销掉中心域相关内容:
#mydomain =
使用查找表
#myorigin =
虚拟域的内容对接方式:
1、postmap生成hash文件
2、mysql
虚拟域
用户别名
用户账号:虚拟账号

使用mysql进行虚拟用户认证支撑邮件服务器
发邮件SMTP:postfix --> sasl --> Courier-authlib --> mysql server
收邮件POP3:Dovecot --> mysql driver --> mysql server
web邮箱:
webmail:httpd
Extmail
Extman

邮件服务系列之虚拟域、虚拟用户和webmail
安装Courier-authlib
yum install expect
tar xf courier-authlib-0.65.0.tar.bz2
cd courier-authlib-0.65.0
./configure --prefix=/usr/local/courier-authlib --sysconfdir=/etc --without-authpam --without-authshadow --without-authvchkpw --without-authpgsql --with-authmysql --with-mysql-libs=/usr/lib/mysql --with-mysql-includes=/usr/include/mysql --with-redhat --with-authmysqlrc=/etc/authmysqlrc --with-authdaemonrc=/etc/authdoemonrc --with-mailuser=postfix --with-mailgroup=postfix --with-ltdl-lib=/usr/lib --with-ltdl-include=/usr/include --with-sqlite-libs=/usr/lib --with-sqlite-includes=/usr/include
make && make install

备注:可以使用--with-authdaemonvar=/var/spool/authdaemon选项来指定进程套接字目录路径
备注:在RHEL5上要使用0.64.0及之前版本,否则,可能会由于sqlite版本过低问题导致configure检查无法通过或编译无法进行

chmod 755 /usr/local/courier-authlib/var/spool/authdaemon
cp /etc/authdaemonrc.dist /etc/suthdoemonrc
cp /etc/authmysqlrc.dist /etc/authmysqlrc
修改/etc/authdoemonrc文件
authmodulelist="authmysql"
authmodulelistorig="authmysql"
daemons=10

检测ltdl安装情况:动态模块加载器
yum list all|grep ltdl
确保libtool-ltdl.i386和libtool-ltdl-devel.i386已经安装
yum -y install libtool-ltdl libtool-ltdl-devel

配置其通过mysql进行邮件账号认证
编辑/etc/authmysqlrc为一下内容,其中2525,2525位postfix用户的UID和GID
MYSQL_SERVER localhost
MYSQL_PORT 3306 # 指定你的mysql监听的端口,这里使用默认的3306
MYSQL_USERNAME extmail # 这时为后文要用的数据库的所有者的用户名
MYSQL_PASSWORD extmail # 密码
MYSQL_SOCKET /var/lib/mysql/mysql.sock
MYSQL_DATABASE extmail
MYSQL_USER_TABLE mailbox
MYSQL_CRYPT_PWFIELD password
MYSQL_UID_FIELD '2525'
MYSQL_GID_FIELD '2525'
MYSQL_LOGIN_FIELD username
MYSQL_HOME_FIELD concat('/var/mailbox/',homedir)
MYSQL_NAME_FIELD name
MYSQL_MAILDIR_FIELD concat('/var/mailbox/',maildir)

加载SysV服务
cp courier-authlib.sysvinit /etc/rc.d/init.d/courier-authlib
chmod 755 /etc/rc.d/init.d/courier-authlib
chkconfig --add courier-authlib
chkconfig --level 2345 courier-authlib on
echo "/usr/local/courier-authlib/lib/courier-authlib" >> /etc/ld.so.conf.d/courier-authlib.conf
ldconfig -v
service courier-authlib start

配置postfix和courier-authlib
虚拟用户:
Maildir:/var/mailbox/
新建虚拟用户邮箱所在的目录,并将其权限赋予postfix用户:
mkdir -pv /var/mailbox
chown -R postfix /var/mailbox

接下来重新配置SMTP认证,编辑/usr/lib/sasl2/smtpd.conf,确保其为以下内容
pwcheck_method:authdaemond
log_level:3
mech_list:PLAIN LOGIN
authdaemond_path:/usr/local/courier-authlib/var/spool/authdaemon/socket
让postfix支持虚拟域和虚拟用户
编辑/etc/postfix/main.cf,添加如下内容:
#######################Virtual Mailbox Settings############################
virtual_mailbox_base = /var/mailbox
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domain_maps.cf
virtual_alias_domains =
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_uid_maps = static:2525
virtual_gid_maps = static:2525
virtual_transport = virtual
maildrop_destination_recipient_limit = 1
maildrop_destination_concurrency_limit = 1
################################QUOTA Settins###############################
message_size_limit = 14336000 # 每封邮件大小限制
virtual_mailbox_limit = 20971520 # 每个用户邮箱大小限制
virtual_create_maildirsize = yes
virtual_mailbox_extended = yes
virtual_mailbox_limit_maps = mysql:/etc/postfix/mysql_virtual_mailbox_limit_maps.cf
virtual_mailbox_limit_override = yes
virtual_maildir_limit_message = Sorry, the user's maildir has overdrawn his diskspace quota, please Tidy your mailbox and try again later.
virtual_overquota_bounce = yes

使用extman源码目录下docs目录中的extmail.sql和init.sql建立数据库:
tar zxvf extman-1.1.tar.gz
cd extman-1.1
mysql -u root -p < exmail.sql
mysql -u root -p < init.sql
cp mysql* /etc/postfix/

授予用户extmail访问extmail数据库的权限
mysql> GRANT all privileges on extmail.* TO extmail@localhost IDENTIFIED BY 'extmail';
mysql> GRANT all privileges on extmail.* TO extmail@127.0.0.1 IDENTIFIED BY 'extmail';
mysql> FLUSH PRIVILEGES;

说明:
1、启用虚拟域以后,需要取消中心域,即注释掉myhostname,mydestination,mydomain,myorigin几个指令,当然,你也可以把mydestination的值改为你自己需要的。
2、对于mysql-5.1之后的版本,其中的服务脚本extmail.sql执行会有语法错误;extmail.sql文件中的TYPE=MyISAM字段在5.1之后TYPE选项不支持,应改为ENGINE;如:# sed -i 's@TYPE=MyISQM@ENGINE=InnoDB@g' extmail.sql

安装httpd
yum install httpd

配置dovecot
vim /etc/dovecot.conf # 按照以下内容找到对应行取消注释并修改args = 内容,将无需使用sql对接的pam等认证取消
mail_location = maildir:/var/mailbox/%d/%n/Maildir
....
auth default {
mechanisms = plain
passdb sql {
args = /etc/dovecot-mysql.conf
}
userdb sql {
args = /etc/dovecot-mysql.conf
}
....

vim /etc/dovecot-mysql.conf
driver = mysql
connect = host=localhost dbname=extmail user=extmail password=extmail
default_pass_scheme = CRYPT
password_query = SELECT username AS user,password AS password FROM mailbox WHERE username = '%u'
user_query = SELECT maildir,uidnumber AS uid,gidnumber AS gid FROM mailbox WHERE username = '%u'

说明:如果mysql服务器是本地主机,即host=localhost时,如果mysql.sock文件不是默认/var/lib/mysql/mysql.sock,可使用host="sock文件路径"来指定新位置;

接下来启动dovecot服务:
service dovecot start
chkconfig dovecot on

安装extmail-1.2
说明:如果extmail的放置路径做了修改,那么配置文件webmail.cf中的/var/www路径必须修改为你所需要的位置。本文默认使用的为/var/www,所以,以下示例中并没有包含路径修改的相关内容

tar zxvf extmail-1.2.tar.gz
mkdir -pv /var/www/extsuite
mv extmail-1.2 /var/www/extsuite/extmail
cp /var/www/extsuite/extmail/webmail.cf.default /var/www/extsuite/extmail/webmail.cf

修改主配置文件
vim /var/www/extsuite/extmail/webmail.cf

部分修改选项的说明:
SYS_MESSAGE_SIZE_LIMIT = 5242880
用户可以发送的最大邮件

SYS_USER_LANG = en_US
语言选项;可该做:
SYS_USER_LANG = zh_CN

SYS_MAILDIR_BASE = /home/domains
此处即为您在前文所设置的用户邮件的存放目录,可改做:
SYS_MAILDIR_BASE = /var/mailbox

SYS_MYSQL_USER = db_user
SYS_MYSQL_PASS = db_pass
以上两句用来设置连接数据库服务器所使用的用户名、密码和邮件服务器用到的数据库,这里修改为:
SYS_MYSQL_USER = extmail
SYS_MYSQL_PASS = extmail

SYS_MYSQL_HOST = localhost
指明数据库服务器主机名,这里默认即可

SYS_MYSQL_TABLE = mailbox
SYS_MYSQL_ATTR_USERNAME = username
SYS_MYSQL_ATTR_DOMAIN = domain
SYS_MYSQL_ATTR_PASSWD = password 以上用来指定验证用户登录里所用到的表,以及用户名、域名和用户密码分别对应表中列的名称,这里默认即可。

SYS_AUTHLIB_SOCKET = /var/spool/authdaemon/socket
此句用来指明authdaemo socket文件的位置,这里修改为:
SYS_AUTHLIB_SOCKET = /usr/local/courier-authlib/var/spool/authdaemon/socket

apache相关配置:
vim httpd.conf
注销中心主机DocumentRoot一行
创建虚拟主机
<VirtualHost *:80>
ServerName mail.magedu.com
DocumentRoot /var/www/extsuite/extmail/html/
ScripAlias /extmail/cgi /var/www/extsuite/extmail/cgi # 指定cgi脚本目录
Alias /extmail /var/www/extsuite/extmail/html # 别名设置
SuexecUserGroup postfix postfix # 如果配置文件改了属组属主不用此项
</VirtualHost>

注解:Suexec:实现仅在运行某些内容时调用指定的用户和组
apache,httpd
User
Group
httpd(apache,apache) --> cgi(postfix,postfix)

找到User项将原来的apache用户改为postfix,Group组也一样将apache改为postfix


修改cgi运行目录的属组属主改为postfix
chown -R postfix.postfix /var/www/extsuite/extmail/cgi

解决依赖关系
extmail将会用perl的Unix::syslogd功能,您可以去http://search.cpan.org搜索下载源码包进行安装
tar zxvf Unix-Syslog-0.100.tar.gz
cd Unix-Syslog-0.100
perl Makefile.PL
make
make install

启动apache服务
service httpd start
chkconfig httpd on

安装extman
tar zxvf extman-1.1.tar.gz
mv extman-1.1 /var/www/extsuite/extman

修改配置文件以符合本例的需要:
cp /var/www/extsuite/extman/webman.cf.default /var/www/extsuite/extman/webman.cf
vim /var/www/extsuite/extman/webman.cf

SYS_MAILDIR_BASE = /home/domains
此处即为您在前文所设置的用户邮件的存放目录,可改做:
SYS_MAILDIR_BASE = /var/mailbox

SYS_DEFAULT_UID = 1000
SYS_DEFAULT_GID = 1000
此两处后面设定的ID号需更改为前面创建的postfix用户和组的ID号
SYS_DEFAULT_UID = 2525
SYS_DEFAULT_GID = 2525

SYS_MYSQL_USER = webman
SYS_MYSQL_PASS = webman
修改为:
SYS_MYSQL_USER = extmail
SYS_MYSQL_PASS = extmail

而后修改cgi目录的属主
chown -R postfix.postfix /var/www/extsuite/extman/cgi/

在apache的主配置文件中Extmail的虚拟主机部分,添加如下两行:
ScriptAlisa /extman/cgi /var/www/extsuite/extman/cgi
Alias /extman /var/www/extsuite/extman/html

创建其运行时所需的临时目录,并修改其相应的权限:
mkdir -pv /tmp/extman
chown postfix.postfix /tmp/extman

如果用户使用webman的话,登录mysql创建用户:
mysql>GRANT ALL PRIVILEGES ON extmail.* TO webman@localhost IDENTIFIED BY 'webman';
mysql>GRANT ALL PRIVILEGES ON extmail.* TO webman@127.0.0.1 IDENTIFIED BY 'webman';
mysql>FULSH PRIVILEGES;

修改
SYS_CAPTCHA_ON = 1

SYS_CAPTCHA_ON = 0

邮件服务系列之pop3s、maildrop
ssl:SMTP.POP3,IMAP4
plaintext:明文,纯文本

http --> https(ssl/tls)
smtps端口:465

S/MIME:由于SMIPS无法保障邮件传输过程的安全因此使用S/MIME进行加密
Security
USER<-->USER
用户证书:
mail,hash(finger print)

OpenSSL,GPG(PGP):PGP是一种技术,GPG是一种软件:GNU Privacy Guard。

PKI:CA

pop3s,imaps:
SSL:会话加密

创建私有CA
cd /etc/pki/CA
(umask 077;openssl genrsa -out private/cakey.pem 2048) #创建私钥
ls private/cakey.pem
openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3656 # 生成自签证书,不加-x509表示生成证书签署请求,
填写证书内容:
Country Name :CN
......:Hebei
......:ZZ
......:MageEdu
......:Tech
......:ca.magedu.com
......:caadmin@magedu.com
完成
编辑证书配置文件:
vim /etc/pki/tls/openssl.cnf
找到
dir项 将=后面改为 /etc/pki/CA
保存退出
mkdir /etc/dovecot/ssl -pv
cd /etc/devecot/ssl
(umask 077;openssl genrsa 1024 > dovecot.key) #生成dovecot私钥
openssl req -new -key dovecot.key -out dovecot.csr # 生成证书签署请求
填写证书内容:
Country Name :CN
......:Hebei
......:ZZ
......:MageEdu
......:Tech
......:mail.magedu.com
......:postadmin@magedu.com
完成

此时使用服务器签署一下即可
cd /etc/pki/CA
mkdir certs newcerts crl
touch index.txt
echo 01 > serial
cd /etc/dovecot/ssl
openssl ca -in dovecot.csr -out dovecot.crt -days 3656
签署成功将dovecot.csr文件改为其他用户无任何权限
编辑dovecot配置文件支持pop3s
vim /etc/dovecot.conf
找到protocols = pop3 pop3s #添加pop3s
注:pop3s:995/tcp imaps:993/tcp
找到ssl相关内容
ssl_listen =
ssl_disable = no
ssl_cert_file = /etc/dovecot/ssl/dovecot.crt
ssl_key_file = /etc/dovecot/ssl/dovecot.key
如果私钥有密码需要添加如下内容:
ssl_key_password = password
保存退出
service dovecot restart
netstat -tnlp
查看是否有995监听
远程测试使用以下命令:
openssl s_client -connect SERVER:PORT -CAfile /path/to/CA_CERT
使用mutt登录加密传输邮件
mutt -f pops://hadoop@magedu.com@172.16.100.1
登陆后服务器方会发来认证证书,提问是否接受r表示拒绝,o表示接受一次,选择o
成功创建会话,输入密码即可登录
整个过程均为加密过程

抓包分析通信过程:借助协议报文分析器
tcpdump:linux自带抓包工具,支持多种协议的分析,需要捕包库支持
sniffer:商业工具
wireshark(GUI):图形化工具
tshark(CLI):命令行工具,wireshark的命令行版

tcpdump [options] 过滤条件
例如:tcp src host 172.16.100.1
tcp src or dst port 21
获取报文的条件:
udp dst port 53
tcp src or dst port 21 AND src host 172.16.100.1
tcp port 21 AND host 172.16.100.1

src发送端
dst接受端

tcpdump [ -DenNqvX ] [ -c count ] [ -F file ] [ -i interface ] [ -r file ]
[ -s snaplen ] [ -w file ] [ expression ]

抓包选项:
-c:指定要抓取的包数量。注意,是最终要获取这么多个包。例如,指定"-c 10"将获取10个包,但可能已经处理了100个包,只不过只有10个包是满足条件的包。
-i interface:指定tcpdump需要监听的接口。若未指定该选项,将从系统接口列表中搜寻编号最小的已配置好的接口(不包括loopback接口,要抓取loopback接口使用tcpdump -i lo),
:一旦找到第一个符合条件的接口,搜寻马上结束。可以使用'any'关键字表示所有网络接口。
-n:对地址以数字方式显式,否则显式为主机名,也就是说-n选项不做主机名解析。
-nn:除了-n的作用外,还把端口显示为数值,否则显示端口服务名。
-N:不打印出host的域名部分。例如tcpdump将会打印'nic'而不是'nic.ddn.mil'。
-P:指定要抓取的包是流入还是流出的包。可以给定的值为"in"、"out"和"inout",默认为"inout"。
-s len:设置tcpdump的数据包抓取长度为len,如果不设置默认将会是65535字节。对于要抓取的数据包较大时,长度设置不够可能会产生包截断,若出现包截断,
:输出行中会出现"[|proto]"的标志(proto实际会显示为协议名)。但是抓取len越长,包的处理时间越长,并且会减少tcpdump可缓存的数据包的数量,
:从而会导致数据包的丢失,所以在能抓取我们想要的包的前提下,抓取长度越小越好。

输出选项:
-e:输出的每行中都将包括数据链路层头部信息,例如源MAC和目标MAC。
-q:快速打印输出。即打印很少的协议相关信息,从而输出行都比较简短。
-X:输出包的头部数据,会以16进制和ASCII两种方式同时输出。
-XX:输出包的头部数据,会以16进制和ASCII两种方式同时输出,更详细。
-v:当分析和打印的时候,产生详细的输出。
-vv:产生比-v更详细的输出。
-vvv:产生比-vv更详细的输出。

其他功能性选项:
-D:列出可用于抓包的接口。将会列出接口的数值编号和接口名,它们都可以用于"-i"后。
-F:从文件中读取抓包的表达式。若使用该选项,则命令行中给定的其他表达式都将失效。
-w:将抓包数据输出到文件中而不是标准输出。可以同时配合"-G time"选项使得输出文件每time秒就自动切换到另一个文件。可通过"-r"选项载入这些文件以进行分析和打印。
-r:从给定的数据包文件中读取数据。使用"-"表示从标准输入中读取。

垃圾邮件过滤方式:

关闭OpenRelay

RBL:Realtime Black List 实时黑名单(付费)
由互联网上的很多组织来维护

内容过滤器:
APACHE:SpamAssassin:垃圾邮件刺客
Perl语言开发:垃圾邮件分拣器
根据垃圾邮件特征码分析
注解:Perl解释型语言,因此性能表现不太出色
病毒邮件网关:
clamav:开源杀毒软件
病毒邮件服务器网关

呼叫器:caller,与邮件服务器进行交互分析过滤作用
MIMEDefang,Mailscanner,Amavisd-new(开源组件,常用)
通过Amavisd-new调用SpamAssassin和clamav

perl:CPAN

配置postfix使用maildrop投递邮件
自带邮件过滤功能,属于courier旗下软件
安装:
将courier-authlib的头文件及库文件链接至/usr目录
ln -sv /usr/local/courier-authlib/bin/courierauthconfig /usr/bin
ln -sv /usr/local/courier-authlib/include/* /usr/include

maildrop需要pcre的支持,因此,需要实现提供pcre的头文件及库文件等开发组件,如果选择以yum源来提供pcre,请确保安装pcre-devel包
yum -y install pcre-devel

groupadd -g 1001 vmail
useradd -g vmail -u 1001 -M -s /sbin/nologin vmail
tar jxvf maildrop-2.6.0.tar.bz2
cd maildrop-2.6.0
./configure --enable-sendmail=/usr/sbin/sendmail --enable-trusted-users='root vmail' --enable-syslog=1 --enable-maildirquoto --enable-maildrop-uid=1001 --enable-maildrop-gid=1001 --with-trashquoto --with-dirsync
make
make install
检查安装结果,请确保有"Courier Authentication library extension enable."这句话出现

maildrop -v 检查安装结果,是否支持courier authlib library是否已开启

新建其配置文件/etc/maildroprc文件,首先指定maildrop的日志记录位置;
vim /etc/maildroprc
添加:
logfile "/var/log/maildrop.log"
保存退出
#touch /var/log/maildrop.log
#chown vmail.vmail /var/log/maildrop.log

配置postfix
编辑master.cf
vim /etc/postfix/master.cf
启用如下两行:
maildrop unix - n n - - pipe
flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient}
注意:定义transport的时候,即如上两行中的第二行,其参数行必须以空格开头,否则会出错。

编辑main.cf
vim /etc/postfix/main.cf
virtual_transport = virtual
修改为:
virtual_transport = maildrop

将下面两项指定的UID和GID作相应的修改:
virtual_uid_maps = static:2525
virtual_uid_maps = static:2525
修改为:
virtual_uid_maps = static:1001
virtual_uid_maps = static:1001

编辑/etc/authmysqlrc
vim /etc/authmysqlrc
MYSQL_UID_FIELD '2525'
MYSQL_GID_FIELD '2525'
修改为:
MYSQL_UID_FIELD '1001'
MYSQL_GID_FIELD '1001'
注意:没有此处的修改,maildrop可能会报告“signal 0x06”的错误报告

编辑/etc/httpd/httpd.conf,修改运行用户:
如果启用了suexec的功能,则将虚拟主机中指定的
SuexecUserGroup postfix postfix
修改为:
SuexecUserGroup vmail vmail

如果没有使用上面的功能,则修改User和Group指令后的用户为vmail
将前文中的如下项:
User postfix
Group postfix
修改为:
User vmail
Group vmail

将用户邮件所在的目录/var/mailbox和extman的临时目录/tmp/extman的属主和属组指定为vmail
chown -R vmail.vmail /var/mailbox
chown -R vmail.vmail /tmp/extman

修改extman的主配置文件中的默认用户ID和组ID,确保其为类似如下内容:
vim /var/www/extsuite/extman/webman.cf
SYS_DEFAULT_UID = 1001
SYS_DEFAULT_GID = 1001

验证:
接下来重启postfix和apache,进行发新测试后,如果日志中的记录类同以下项,则安装成功
(delivered via maildrop service)并且relay=maildrop即可

Name Resolve:Username --> UID,Group --> GID,Service Name --> PORT,HOSTNAME --> IP
Username --> UID:/etc/passwd
Hostname --> IP:DNS,/etc/hosts
Service Name --> Ports:/etc/services,MYSQL:services,ports
只要一种数据存储格式:解析库,不同的解析库需要不同的查询方式

nsswitch:nsswitch是一个框架,用于完成不同解析库的解析

ftp服务
File Transfer Protocol 文件传输协议
21/tcp
文件共享服务:应用层协议,ftp

NFS:Network File System(RPC:Remote Procedure Call,远程过程调用)
能够让位于不同主机上的两个进程能够基于二进制的格式实现数据通信
Samba:CIFS/SMB,

FTP:有两个链接
1、命令链接,控制链接(建立链接)连接后持续打开状态;21/tcp
2、数据链接(传输)发起请求时打开,传输完成断开。
主动模式:
20/tcp 服务器端发起请求向客户端传输数据
被动模式:
端口随机,有服务器端发起两个字符串给客户端,由客户端按照这两个字符串生成随机端口,第一个字符串乘以256再加第二个字符串为随机端口号。有效的避免客户端防火墙拒绝的问题。

数据传输模式(自动选择):传输遵循传输文件本身格式
二进制:
文本:
ftp Server --> ftp client

上传下载命令:
get:下载单个文件
put:上传单个文件
mget:下载多个文件
mput:上传多个文件

数据类型:
结构化数据
半结构化数据
非结构化数据

FTP服务器端软件:
Linux:
wu-ftpd:华盛顿大学FTP
vsftpd:Very Secure Ftp Daemon
proftpd:
pureftpd
win:
Serv-U
Filezilla(Linux也支持)

FTP客户端程序:
CLI:
ftp
lftp
GUI:
gftpd
FlashFxp
Cuteftp
Filezilla

vsftpd:
/etc/vsftpd:配置文件目录
/etc/init.d/vsftpd:服务脚本
/usr/sbin/vsftpd:主程序
/var/ftp:放置文件目录,此目录对于vsftp进程来说不能有写权限,在此目录下创建子目录给予ftp权限


基于PAM实现用户认证:
/etc/pam.d/*
/lib/security/*
/lib64/security/*
支持虚拟用户

安装vsftp
更新yum源
yum install fsftpd
ftp:无论哪种用户最终都会映射给一个系统用户
匿名用户 --> 系统用户
虚拟用户
系统用户 --> 系统用户
/var/ftp:ftp用户的家目录
匿名用户访问目录,因为被映射给了ftp用户
service vsftpd start 启动
chkconfig vsftpd on
使用anonymous匿名用户登录
登陆后执行help可以查看可执行命令
chroot:锁定用户根目录
cd /etc/vsftpd
cp vsftpd.conf vsftpd.conf.bak
man vsftpd.conf
通过查看帮助文档了解各功能打开关闭选项详情
getenforce # 查看SELinux状态
setenforce 0 # 关闭SELinux
vim vsftpd.conf
anonymous_enable = YES # 是否启用匿名用户
local enable = YES # 是否启用系统用户
write_enable = YES # 系统用户是否可以上传文件
anon_upload_enable = YES # 是否允许匿名用户上传文件
anon_mkdir_write_enable = YES # 是否允许匿名用户创建文件
anon_other_write_enable = YES # 是否允许匿名用户其他写权限
需要在上传目录设置ftp写权限:
#setfacl -m u:ftp:rwx /var/ftp/upload
#getfacl /var/ftp/upload # 查看权限信息

dirmessage_enable=YES # 登录至某目录显示欢迎信息,在登录的默认目录下创建.message文件写提示语保存即可,ftp账户登录至此目录就会显示输入的提示语。
xferlog_enable=YES # 打开传输日志信息
xferlog_file=/var/log/xferlog # 打开日志存储文件位置
xferlog_std_format=YES # 日志标准格式
chown_uploads=YES # 是否允许当用户完成文件上传后是否把用户属组属主改为其他用户
chown_username=whoever # 改为哪个用户,与上一条搭配使用
idle_session_timeout=600 # 定义会话超时时间,超过600秒断开用户会话控制连接
data_connection_timeout=120 # 定义数据传输超时时间,超过120秒不传输数据断开连接
ascii_upload_enable=YES # 是否启用文本模式上传功能,如果打开只使用纯文本模式上传文件
ascii_download_enable=YES # 是否启用文本模式下载功能,如果打开只使用纯文本模式下载文件
chroot_list_enable=YES # 是否用一个文件将特定用户锁在家目录下
chroot_list_file=/etc/vsftpd/chroot_list # 在哪个文件中创建一个用户列表,将列表中用户禁锢在杂技目录中,与上一条搭配使用
如:创建文件vim /etc/vsftpd/chroot_list,添加用户名 hadoop 保存退出,重启服务
如果嫌弃一个个用户填写太麻烦可以使用以下参数:
chroot_local_user=YES # 此时将所有系统用户全部禁锢在家目录下
listen=YES # vsftpd是否工作在一个独立守护进程
改为瞬时守护进程方法:
/etc/xinetd.d/目录下创建一个vsftpd的脚本即可
守护进程;
独立守护进程:用于用户量较大,连接时间较长的场景
瞬时守护进程:不需要关联至运行级别,用户量访问较小,访问时间较短的场景
由超级守护进程xinetd代为管理,xinetd是一个独立守护进程
pam_service_name=vsftpd # 定义pam相关配置文件名称
userlist_enable=YES # 所有写在/etc/vsftpd/ftpusers文件中的用户都禁止访问FTP,pam.d/vsftpd文件中指定了此文件拒绝访问的内容。
userlist_deny=YES # 拒绝userlist访问列表中的用户访问FTP,改为NO为仅允许列表内用户登录,其他用户不能登录
max_clients=# # 允许最大的访问客户端数
max_per_ip=# # 同一个IP最多可同时发起多少连接数
tcp_wrappers=YES #

vsftpd支持两种安全通信方式:
ftps:ftps_ssl/tls
1、创建证书和秘钥文件
cd /etc/pki/CA
mkdir certs newcerts crl
touch index.txt
echo 01 > serial
(umask 077:openssl genrsa -out private/caksy.pem 2048)
openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days=3650
CN
Hebei
SJZ
MageEdu
Tech
ca.magedu.com
完成证书创建
mkdir /etc/vsftpd/ssl
cd /etc/vsftpd/ssl
(umask 077:openssl genrsa -out vsftpd.key2048)
openssl req -new -key vsftpd.key -out vsftpd.csr
CN
Hebei
SJZ
MageEdu
Tech
ftp.magedu.com
完成私钥创建

vim /etc/pki/tls/openssl.cnf
dir = /etc/pki/CA
保存退出
openssl ca -in vsftpd.csr -out vsftpd.crt # 签署证书

2、在vsftpd.conf文件中添加如下内容:
ssl_enable=YES # 启用ssl功能
ssl_tlsv1=YES # 支持tlsv1版本ssl
ssl_sslv2=YES
ssl_sslv3=YES # 支持sslv3版本
allow_anon_ssl=NO # 匿名是否启用ssl
force_local_data_ssl=YES # 强制本地用户传输使用ssl
force_local_login_ssl=YES # 强制本地用户登录使用ssl
rsa_cert_file=/etc/vsftpd/ssl/vsftpd_crt # 使用的证书文件
rsa_private_key_file=/etc/vsftpd/ssl/vsftpd.key # 使用的秘钥文件
保存退出
重启服务
sftp:OpenSSH,SubSystem,sftp(SSH)

chroot:禁锢用户于其家目录中
文件服务权限:
文件系统权限*文件共享权限

vsftpd:PAM(手动定义配置文件)
虚拟用户:
mysql:VSFTPD,users;Name,Password
/etc/vsftpd/vusers --> db_load 使用db4-utils包实现转换为二进制格式文件
USERNAME
PASSWORD

ftp用户使用mysql数据库管理:
1、事先安装好开发环境和mysql数据库
yum -y install mysql-server mysql-devel
yum -y groupinstall "Development Libraries" # 准备好开发包组

2、安装pam_mysql-0.7RC1
tar zxvf pam_mysql-0.7RC1.tar.gz
cd pam_mysql-0.7RC1
./configure --with-mysql=/usr/local/mysql --with-openssl
make && make install
cp /usr/lib/security/pam_mysql.so /lib/security/

3、安装vsftpd-2.0.5
mkdir -pv /usr/share/empty /var/ftp
useradd -s /bin/false -d /var/ftp ftp
tar zxvf vsftpd-2.0.5.tar.gz
cd vsftpd-2.0.5
make && make install

安装配置文件
cp vsftpd.conf /etc

编辑配置文件/etc/vsftpd.conf
添加:listen=YES

启动服务器:
/usr/local/sbin/vsftpd &
chmod og-w /var/ftp

配置
1、准备数据库及相关表
再次,我们建立名为vsftp的数据库来存放相关虚拟用户的账号
mysql>create database vsftp;
mysql>grant select an vsftp.* to vsftpd@localhost identified by '123456';
mysql>grant select an vsftp.* to vsftpd@127.0.0.1 identified by '123456';
mysql>flush privileges;
mysql>use vsftp;
mysql>create table users (
id int AUTO_INCREMENT NOT NULL,
name char(20) binary NOT NULL,
paaswd char(48) binary NOT NULL,
primary key(id)
);
添加测试的虚拟用户,其密码采取加密存放的方式
mysql>insert into users(name,passwd) values('benet',password('123456'));
mysql>insert into users(name,passwd) values('apatech',password('123456'));

查看结果
mysql> select * from users;

2、建立pam认证所需文件
vim /etc/pam.d/vsftp.mysql
添加如下两行:
auth required /lib/security/pam_mysql.so user=vsftpd passwd=123456 host=localhost db=vsftp tables=users userclumn-name passwdcolumn=passwd crypt=2
account required /lib/security/pam_mysql.so user=vsftpd passwd=123456 host=localhost db=vsftp tables=users userclumn-name passwdcolumn=passwd crypt=2

注解:crypt参数详解
此参数为0时密码以明文存放,为1表示,为2时表示用mysql数据库方式以密文存放,为3是MD5方式加密,为4以SHA1方式加密。启用加密方式存放,可能会导致ftp虚拟用户无法正常登陆,密码验证可能无法通过。

3、修改vsftpd的配置文件,使其适应mysql认证
建立虚拟用户映射的系统用户及对应的目录
useradd -s /sbin/nologin -d /var/ftp2 vsftp
chmod go+rx /var/ftp2

请确保/etc/vsftpd.conf中已经启用了以下选项
anonymous_enable=YES
local_enable=YES
write_enable=YES
anon_upload_enable=NO
anon_mkdir_write_enable=NO
chroot_local_user=YES

添加一下选项:
guest_enable=YES # 允许来宾用户访问
guest_username=vsftp # 来宾用户映射给哪个系统用户
listen=YES
pam_service_name=vsftpd.mysql # 认证使用mysql方式

为不同用户创建不同权限:
vim /etc/vsftpd.conf
user_config_dir=/etc/vsftpd/vusers_dir
保存退出
mkdir /etc/vsftpd/vusers_dir/
touch tony peter
vim tony
anon_upload_enable=NO
anon_mkdir_write_enable=NO
vim peter
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES

启动vsftpd服务
/usr/local/sbin/vsftpd &

查看端口开启情况

netstat -tnlp|grep :21

使用虚拟用户登录,验证配置结果,一下为本机的命令方式测试,你也可以再其他win Box上用IE或者FTP客户端工具登录验证。

NFS服务:
Network File System

ext3,ext2:Kernel Space

mke2fs:用户空间,文件系统管理工具

read()和write()均为函数
local procedure call 本地过程调用

RPC:Remote procedure call 远程过程调用

linux:提供rpc服务的程序:portmap:111/tcp,111/udp

RPC:编程技术,简化分布式应用程序的开发,RPC:C --> RPC C --> RPC S --> S

NFS Client --> NFS Server 由RPC完成此过程

web服务:
Browser --> Server html格式

RPC实现:二进制格式,文本格式(XMLRPC)均可 --> SOAP(Simple Object Access Protocol)

NFS:由SUN发开的文件系统
NFSv1-NFSv4

服务器端:nfs-utils
rpm -ql nfs-utils
service nfs start 启动nfs server服务,nfs会启动三个进程,监听在TCP/UDP的2049端口
nfsd:nfs主服务
mountd:接受客户端挂载请求进程,端口半随机
quotad:磁盘配额进程,限制可以在本地使用多大空间,端口半随机,向RPC申请分配的
service portmap status 确保关联服务已经启动,tcp/111 udp/111,与RPC客户端通信使用,向RPC申请分配的
rpcinfo -p localhost 查看所有rpc程序所关联的端口号
/etc/rc.d/init.d/nfs.lock # 锁机制,当一个共享文件由两个程序同时访问时来控制访问的进程。

配置文件:
/etc/exports
man exports 可以查看使用方式
内容格式如下:
/path/to/somedir CLIENT_LIST
多个客户之间使用空白字符分隔
每个客户端后面必须跟一个小括号,里面定义了此客户访问特性,如访问权限等
例如:172.16.0.0/16(ro,async) ro为只读权限,async为异步写入 192.16.0.0/24(rw,sync) rw为读写权限,sync为同步写入

服务端创建过程:
mkdir /shared
vim /etc/exports
内容:
/shared 172.16.0.0/16(ro)
保存退出
service nfs restart
为保障nfs不中断,可以使用以下命令刷新配置
exportfs命令:
-a:跟-r或-u选项同时使用,表示重新挂载所有文件系统或取消导出所有文件系统;
-r:重新导出
-u:取消导出
-v:显示详细信息

showmount -a NFS_SERVER # 查看本地及其被挂载已经挂载的文件系统,以及客户端对应列表
-e NFS_SERVER # 查看本地服务器已经共享的目录,在其他网络主机也可以查看其他服务器的共享目录
-d NFS_SERVER # 显示NFS服务器所有导出的文件系统中被客户端挂载了的文件系统

客户端使用mount命令挂载
mount -t nfs NFS_SERVER:/PATH/TO/SOME_EXPORT /PATH/TO/SOMEWHERE

文件系统导出属性:可以使用man exports查看具体属性参数
ro:只读
rw:读写
async:异步
sync:同步
root_squash:将root用户映射为来宾账号,默认开启;
no_root_squash:root用户映射访问,非常不安全的选项
all_squash:任何用户都映射为来宾账号
anonuid和anongid:指定映射的来宾账号
no_acl:不支持acl


用户权限:
useradd -u 510 nfstest
touch /shared/nfstest
chown nfstest.nfstest /shared/nfstest
vim /etc/exports
/shared 172.16.0.0/16(rw,all_squash,anonuid=510,anongid=510)
客户端重新挂载后
ls -l nfstest目录属组属主为510

自动挂载nfs目录:
vim /etc/fstab
添加一行:
172.16.100.7:/shared /mnt/nfs nfs defaults._rnetdev 0 0
保存退出即可
_rnetdev选项为如果挂在不上可以忽略

让mountd和quotad等进程监听在固定端口,编辑配置文件/etc/sysconfig/nfs
内容:
MOUNTD_PORT=892
QUOTAD_PORT=875
LOCKD_UDPPORT=32769
重启nfs服务即可生效

iptables系列之基础原理
iptables不是服务,但有服务脚本,服务脚本的主要作用在于管理保存的规则
装载及移除iptables/netfilter相关的内核模块:
iptables_nat,iptables_filter,iptables_mangle,iptables_raw,ip_nat,ip_conntrack

linux:网络防火墙
netfilter:Frame
iptables:数据报文过滤,NAT、mangle等规则生成的工具

MSL:Maximum Segment Lifetime 最大生存时长,一般为120秒

防火墙:硬件,软件:规则(匹配标准,处理办法)
Framework:框架
默认规则:
开放:堵
关闭:通

规则:匹配标准
IP:SIP源IP,DIP目标IP
TCP:SPORT源端口,DPORT目标端口,1次握手状态:SYN=1,FIN=0,RST=0,ACK=0; 2次握手状态:SYN=1,ACK=1,FIN=0,RST=0; 3次握手状态:ACK=1,SYN=0,RST=0,FIN=0(ESTABLISHED)
UDP:SPORT,DPORT目标端口
ICMP:icmp-type

数据报文过滤

早期Linux没有防火墙,移至了OpenBSD的机制

Linux2.0:ipfw/firewall
Linux2.2:ipchain/firewall
Linux2.4:iptables/netfilter

hook function:钩子函数,每个钩子函数对应一个链
prerouting:路由之前
input:进入
output:发出
forward:转发
postrouting:路由之后

规则链:
PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING

filter(过滤):表
INPUT
OUTPUT
FORWARD

NAT(地址转换):表
PREROUTING
POSTROUTING

mangle(修改报文首部):表
拆开、修改、封装
PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING

raw():表
PREROUTING
OUTPUT

规则先后次序:
PREROUTING:raw --> mangle --> nat --> filter
INPUT:mangle --> filter
FORWARD:mangle --> filter
OUTPUT:raw --> mangle --> nat --> filter
POSTROUTING:mangle --> nat

自定义链:
被默认链调用后才能发挥作用,而且如果没有被任何自定义链中的任何规则匹配,还应该有返回机制;
用户可以删除自定义的空链
默认链无法删除

每个规则都有2个内置的计数器
1、被匹配到的报文个数
2、被匹配到的报文体积之和

规则:匹配标准,处理动作

常见使用格式:
iptables [-t TABLE] COMMAND CHAIN [num] 匹配标准 -j 处理办法

iptables启动时会加载/etc/sysconfig/iptables文件,使用命令添加的条目会保存在此文件中才可以永久有效
因此 使用命令添加的规则,需要使用 service iptabels save 即可保存规则,否则重启后即便失效

匹配标准:
通用匹配
-s.--src 源地址
-d,--dst 目标地址
-p {tcp|udp|icmp} 指定协议
-i interface 指定数据报文流入的接口
可用于定义标准的链:PREROUTING,INPUT,FORWARD
-o interface 指定数据报文流出的接口
可用于标准定义的链:OUPUT,POSTROUTING,FORWARD
-j TARGET 跳转
ACCEPT 允许通过
DROP 丢弃,悄悄丢弃
REJECT 拒绝
LOG 并不做用户请求去向的处置,只是记录日志,log一定要放在前面,否则匹配到之后不再追溯后面的内容,就不会记录日志
--log-level level:指定日志级别
--log-prefix prefix:log的前缀
--log-tcp-sequence:tcp的序列号
--log-tcp-options:tcp报文选项
--log-ip-options:ip报文选项
--log-uid:哪个用户请求的,请求用户的UID
例:iptables -I INPUT 4 -d 172.16.100.7 -p icmp --icmp-type 8 -j LOG --log-perfix "---firewall log for icmp---"
记录日志ping本机的内容,并加前缀信息,查看tail -f /var/massages看到日志内容

扩展匹配:依赖于模块.so文件
隐含扩展:不需特别指明由哪个模块进行的扩展,因为此时使用-p{tcp|udp|icmp}已指明
-p tcp
--sport PORT[-PORT]:源端口,可以后面加-port指定一堆连续的端口
--dport PORT[-PORT]:目标端口,同上
--tcp-flags mask comp:只检查mask指定的标志位,是逗号分隔的标志位列表,comp:此列表中的位必须为1,而mask中出现的,必须为0;
如:--tcp-flags SYN,FIN.ACK,RST SYN,ACK = --syn
--syn:表示TCP三次握手中的第一次
-p icmp
--icmp-type:
0:echo-reply,响应报文
8:echo-request,请求报文

-p udp
--sport
--dport

显示扩展:使用额外的匹配机制。必须指明由哪个模块进行的扩展,在iptables中使用-m选项可完成此功能
-m EXTESTION --spe-opt
-m state:状态扩展
结合ip_conntrack追踪会话的状态
NEW:新连接情求
ESTABLISHED:已建立的链接
INVALID:非法连接请求
RELATED:相关联的
-m state --state NEW,ESTABLISHED -j ACCEPT # 状态是NEW和ESTABLISHED的数据报放行

-m multiport:离散的多端口匹配扩展
--source-ports:源端口
--destination-ports:目标端口
--ports:不区分源和目标,只要是端口就匹配
例:表示21,22,80端口全部打开并做状态追踪
-m multipor --destination-ports 21,22,80 -m state --state NEW -j ACCEPT

-m iprange:ip地址范围取值的扩展功能
--src-range
--dst-range

-m connlimit:连接数限制
! --connlimit-above n :给出连接最大数值,n为数值,允许情况下前面需要加!使用。
例:iptables -A INPUT -d 172.16.100.7 -p tcp --dport 80 -m connlimit ! --connlimit-above 2 -j ACCEPT # 表示低于2个的允许,如果不加!号,最后应该是-j DROP

-m limit:限制请求数量
--limit RATE:明确速率,单位时间内最多允许放行的数量
--limit-burst num:蜂拥而至的数量最多允许多少
例:iptables -I INPUT -d 172.16.100.7 -p tcp -dport 22 -m limit --limit 3/minute --limit-burst 3 -j ACCEPT
表示本机的22端口链接数量最多每秒允许3个请求进入,并且峰值也仅允许3个进入
iptables -A INPUT -d 172.16.100.7 -p icmp --icmp-type 8 -dport 22 -m limit --limit 3/minute --limit-burst 3 -j ACCEPT
iptables -R OUTPUT 1 -s 172.16.100.7 -m state --state ESTABLISHED,RELATED -j ACCEPT
以上两条将进出ping都打开,接下来我们更改为限制模式:
iptables -R INPUT 3 -d 172.16.100.7 -p icmp --icmp-type 8 -m limit --limit 5/minute --limit-burst 6 -j ACCEPT
测试过程不易过快,否则无法测出效果,限定每秒1个ping请求处理,此时使用ping -t 172.16.100.7进行ping请求测试

-m string:字符串匹配,根据某种字符串匹配不同策略2.6.14以后版本才支持此选项。
--algo bm|kmp:bm和kmp是两种不同算法,区别不大
--string "pattern":匹配哪一个字符串,请求中包含此字符串则会拒绝或者放行
例:在httpd的访问页面文件中含有h7n9内容,测试访问是否正常,测试屏蔽此字符
iptables -I OUTPUT -s 172.16.100.7 -m string --algo kmp --string "h7n9" -j REJECT

范围取反:
可以使用!条件取反
例如:-s 172.16.100.7 表示源端为172.16.100.7但是中间加!取反 -s ! 172.16.100.7则表达为除172.16.100.7意外的IP均为源端
ip范围取值显示扩展的方式,也支持取反同样是加!号:
iptables -A INPUT -p tcp -m iprange --src-range 172.16.100.3-172.16.100.100 --dport 22 -m --state NEW,ESTABLISHED -j ACCEPT

开启ssh端口对服务器的访问例子:
iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.7 -p tcp --dport 22 -j ACCEPT
iptables -t filter -A OUTPUT -s 172.16.100.7 -d 172.16.0.0/16 -p tcp --sport 22 -j ACCEPT

允许本机ping任意主机但拒绝其他主机ping:
iptables -A OUTPUT -s 172.16.100.7 -p icmp --icmp-type 8 -j ACCEPT
iptables -A INPUT -d 172.16.100.7 -p icmp --icmp-type 0 -j ACCEPT

放行外部主机ping本机:
iptables -A INPUT -d 172.16.100.7 -p icmp --icmp-type 8 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -s 172.16.100.7 -p icmp --icmp-type 0 -m state --state ESTABLISHED -j ACCEPT

允许udp和tcp 53端口访问并解析,需要8条规则

sshd和httpd服务器防火墙策略,并开通追踪功能:
iptables -A INPUT -d 172.16.100.7 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -s 172.16.100.7 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -A INPUT -d 172.16.100.7 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -s 172.16.100.7 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
使用iptstate命令查看链接状态,已经可以看到端口链接情况并且可看到已连接状态的TTL为120小时倒计时(5天)状态,如果连接一直不断开此条目会一直存放,因此可能会导致不停存放无法释放的情况。
sysctl -w net.ipv4.ip_conntrack_max=65536 # 增加条目数量到65536
cat /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_established #能查看最大超时时长 432000秒
通过sysctl命令写入只是临时生效,永久生效需要如下操作:
vim /etc/sysctl.conf
添加:
sysctl -w net.ipv4.ip_conntrack_max=65536

用一条规则全部囊括以上规则:
iptables -I OUTPUT -s 172.16.100.7 -m state --state ESTABLISHED -j ACCEPT # 所有端口全部放行,-I表示放置为第一条规则

删除之前所有规则:
iptables -D OUTPUT 2 # 从第二条删除,可重复执行,因为删除第二条之后,后面的就成为第二条规则。

放行FTP的21端口:
iptables -A INPUT -d 172.16.100.7 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
因为ftp为mysql虚拟用户认证,因此需要放行本地连接
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
此时可以登录成功,但ls无法看到任何数据,因为控制协议打开并未开放传输协议,但是传输协议为随机端口,下面还需进行对应的随机端口的放行
iptables -A INPUT -d 172.16.100.7 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -R OUTPUT 1 -s 172.16.100.7 -m state --state ESTABLISHED,RELATED -j ACCEPT
还需要装载ip_conntrack_ftp和ip_nat_ftp模块
装载模块编辑文件如下:
vim /etc/sysconfig/iptables-config
找到如下添加选项ip_nat_ftp ip_conntrack_ftp即可
IPTABLES_MODULES="ip_nat_ftp ip_conntrack_ftp"


iptables系列之基本应用及显式扩展
iptables命令:可以用man iptables查看具体详情
管理规则:
-A:附加一条规则,添加在链的尾部
-I CHAIN [num]:插入一条规则,插入为对应CHAIN上的第num条,不写num则默认为第一条;
-D CHAIN [num]:删除指定链中的第num条规则;
-R CHAIN [num]:替换指定的规则
管理链
-F [CHAIN]:flush,清空指定规则链,如果省略CHAIN,则可以删除对应表中的所有链
-P CHAIN:设定指定链的默认策略
-N:自定义一个新的空链
-X:删除一个自定义的空链,非空的需要使用-F清空后删除
-Z:置零指定链中所有规则的计数器
-E:重命名自定义的链
查看类:
-L:显示指定表中的所有规则
-n:以数字格式显示主机地址和端口号
-v:显示链及规则的详细信息
-vv或-vvv:按v的出现次数显示更为详尽的内容
-x:显示计数器的精确值
--line-numbers:显示规则号码

动作(target)
ACCEPT:允许通过
DROP:丢弃,悄悄丢弃
REJECT:拒绝通过
DNAT:目标地址转换
SNAT:源地址转换
REDIRECT:端口重定向
MASQUERADE:地址伪装
LOG:记录日志
MARK:给报文加标记

例子:
将默认规则全部清除
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
只保留了22端口的手动添加策略
此时httpd和ping都没有响应
放行对外的80端口
iptables -I INPUT -d 172.16.100.7 -p tcp --dport 80 -j ACCEPT
iptables -I OUTPUT -s 172.16.100.7 -p tcp --sport 80 -j ACCEPT

iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -i lo -j ACCEPT
iptables -A OUTPUT -s 127.0.0.1 -d 127.0.0.1 -o lo -j ACCEPT

ip_conntrack模块:
可以追踪会话过程,无论TCP还是UDP报文
/proc/net/ip_conntrack文件,内核文件,保存当前系统每个客户端与主机建立的链接关系和状态
使用iptstate命令一样可以查到以上文件内容
-t:显示当前主机所有请求状态信息

lsmod|grep ip # 可以查看跟IP网络相关的所有加载模块
modprobe -r ip_conntrack # 卸载ip_conntrack模块,会提示模块正在使用无法移除,即便添加-f强制选项也无法移除,因为此功能均被iptables所调用的,停止iptables服务既可卸载,一旦卸载不会记录追踪。
cat /proc/sys/net/ipv4/ip_conntrack_max # 可以定义ip_conntrack文件最大能保存多少条目,默认32768,如果超出则会超时被丢弃。
因此,在非常繁忙的服务器上就不要启动此模块了。

注解:卸载ip_conntrack模块后,只要使用iptables -t nat -L 就会自动加载此模块,因为iptable_nat与ip_conntrack有依赖关系,因此在负载较高的服务器尽量避免查看nat相关iptables表。有案例因为此命令导致服务器大量连接包被丢弃损失三十万。

保存规则:
service iptabels save # 命令保存规则永久生效,否则重启后规则失效
/etc/sysconfig/iptables
iptables-save > /etc/sysconfig/iptables.20190110
iptabels-restore < /etc/sysconfig/iptables.20190110

流量控制工具:
tc:traffic control
实现流量控制方式:
令牌桶机制:设定一个令牌桶里面只有500个令牌,只有获取令牌的用户才可以获取访问权,回收一定令牌之后再次发放。需要设定一个总量,然后再设定一个同一时间可进如的峰值即可。

iptables系列之nat及其过滤功能
新创建链:
iptables -N clean_in # 自定义创建一条名为clean_in的新链
iptables -L -n # 查看结果有一条references的新链,此为引用链,表示被主链调用的链
iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP # 添加到新链一条规则
iptables -L -n --line-nubmers # 查看结果并且加序列号显示规则
iptables -A clean_in -d 172.16.255.255 -p icmp -j DROP # 继续添加新链来保障主机安全
iptables -A clean_in -p tcp ! --syn -m state --state NEW -j DROP # tcp的同步数据的新数据包
iptables -A clean_in -p tcp --tcp-flags ALL ALL -j DROP
iptables -A clean_in -p tcp --tcp-flags ALL NONE -j DROP
iptables -A clean_in -d 172.16.100.7 -j RETURN # 任何数据报进来先到clean_in链进行清理,均未匹配的转发至主链调用
iptables -I INPUT -j clean_in # 调用规则,先由clean_in处理,然后再回到主链第二条规则匹配
iptables -X clean_in # 删除链,但必须为空链才可删除

利用iptables的recent模块来抵御DOS攻击:
iptables -I 2 INPUT -p tcp -dport 22 -m connlimit --connlimit-above 3 -j DROP
iptables -I 3 INPUT -p tcp -dport 22 -m state --state NEW -m recent --set --name SSH
iptables -I 4 INPUT -p tcp -dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP

recent:即记录最近请求的IP记录保存在名为SSH的空间中,有新用户请求就使用update参数更新此记录,在300s中之内出现了3次请求以上的就拒绝此请求

1、放置在第二条保障优先级,利用connlimit模块将单IP的并发设置为3,;会误杀使用NAT上网的用户,可以根据实际情况增大该值
2、放置在INPUT链的第三条,利用recent和state模块限制单IP在300s内只能与本机建立3个新连接,被限制五分钟后即可恢复访问

下面对最后两句做一个说明:
1、第二句是记录访问tcp 22端口的新连接,记录名称为SSH
--set 记录数据报的来源IP;如果IP已经存在将更新已经存在的条目

2、第三局是指SSH记录中的IP,300s内发起超过3次连接则拒绝此IP的链接。
--update是指每次建立连接都更新列表
--seconds 必须与--rcheck或者--update同时使用
--hitcount必须与--rcheck或者--update同时使用

3、iptables的记录:/proc/net/ipt_recent/SSH

也可以使用下面的这句记录日志:
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --name SSH --second 300s --hitcount 3 -j LOG --log-prefix "SSH Attack"

NAT:Network Address Translation

DNAT:目标地址转换
SNAT:源地址转换(POSTROUTING,OUTPUT)

路由功能也可以将不同网段的地址进行转换:
vim /proc/sys/net/ipv4/ip_forward 默认值为0改为1即可打开路由功能

设置NAT转换防火墙,先清理之前策略:
设置之前要在真实环境中设置两个网络,并在中间防火墙的主机上添加两边网络的网卡。
iptables -P INPUT ACCEPT # 将INPUT链的默认策略改为ACCEPT
iptables -P OUTPUT ACCEPT # 将OUTPUT链的默认策略改为ACCEPT
iptables -F # 清除所有规则
iptables -L -n # 查看规则列表为空
iptables -X clean_in # 删除clean_in链
service iptables save # 保存当前结果
vim /proc/sys/net/ipv4/ip_forward 默认值为0改为1 # 打开转发功能
永久生效:vim /etc/sysctl.conf 将net.ipv4.ip_forward = 1 保存即可
sysctl -p 刷新设置即可生效
更改一台客户端的默认网关:
route del -net 0.0.0.0
route add default gw 172.16.100.7
添加路由之后即可完成互访;
但这样就能完成网络互访为什么还需要NAT呢?
因为假如我们与互联网通信的时候,就无法返回你的主机了,因此要通过NAT转换为本机的公有地址才能回到本机
-j SNAT
--to-source:指定源地址是哪里
例:iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT --to-source 172.16.100.7
使用iptables -t nat -L -n # 查看nat表中是否有新的规则生效

-j MASQUERADE:地址伪装 ,外网地址是动态时使用,但性能效率较低

转发:拒绝192.168.10.0段的所有ping包的转发
iptables -A FORWARD -s 192.168.10.0/24 -p icmp -j REJECT

iptables -P FORWARD DROP # 所有转发全部丢弃
iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 192.168.10.0/24 -p tcp --dport 80 -m state --state NEW -j ACCEPT
iptables -A FORWARD -s 192.168.10.0/24 -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT
iptables -A FORWARD -s 192.168.10.0/24 -p tcp --dport 21 -m state --state NEW -j ACCEPT # 只打开了FTP控制规则
iptables -R FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # 将已连接的添加RELATED即可打开FTP传输规则
使用前必须先打开两个模块:
vim /etc/sysconfig/iptables-config
添加如下模块:
IPTABLES_MODULES="ip_nat_ftp ip_conntrack_ftp"
lsmod|grep ftp # 查看模块是否打开

DNAT:目标地址转换,目标地址转换的链为PREROUTING

-j DNAT
--to-destination IP:[port]
iptabels -t nat -A PREROUTING -d 172.16.100.7 -p tcp -dport 80 -j DNAT --to-destination 192.168.10.22
# 访问外网地址的172.16.100.7的80端口时则跳转为内网的192.168.10.22的80端口
iptabels -t nat -R PREROUTING 1 -d 172.16.100.7 -p tcp -dport 80 -j DNAT --to-destination 192.168.10.22:8080 #上面一条为将刚添加的第一条80端口改为目标地址访问的8080端口,即外网访问172.16.100.7的80端口实际访问的是内网192.168.10.22的8080端口

目标地址转换放行FTP端口比较复杂,因为ftp被动模式时返回端口是随机的。

PNAT:Port NAT,端口转换

# 过滤从外网访问内网的含h7n9内容的web页面都丢弃掉
iptables -A FORWARD -m string --algo kmp --string "h7n9" -j DROP

基于时间做控制的iptables:
因为redhat自带版本没有time模块,因此需要自定义编译安装来支持time模块
需要安装layer7支持功能才可以支持time模块,并且还支持应用级过滤例如迅雷、QQ等

iptables系列之layer7
DMZ:军事化区域

内核编译:
单内核:模块化(文件系统、驱动、安全)
配置:.config(/proc/cpuinfo,lspci,lsusb,hal-device)
make menuconfig
make gconfig
make kconfig
make config
make oldconfig
编译
make
只编译部分源码:
make SUBDIR=arch/
make drivers/net/pcnet32.ko
转存编译结果
make O=/path/to/somewhere
安装内核模块
make module_install
安装内核
make install

make clean:清理之前编译好的二进制模块,清理之前需要备份.config文件,否则将被清理
make mrproper:清理之前编译所残留的任何操作

busybox+kernel = Linux

linux:
开发工具gcc
工程工具make
头文件glibc
微型系统ulibc

layer 7 -- l7
应用:xunlei,qq,netfilter<--path

1、给内核打补丁,并重新编译内核
2、给iptables源码打补丁,并重新编译iptabels
3、安装l7proto

kernel,patch
iptabels,patch

iptables:二、三、四层
string:字符串过滤

netfilter:是一个框架,完成应用级过滤,需要打补丁完成
rules规则依靠iptables来实现,netfilter框架进行补丁升级之后,还需要完善iptables实现相应的规则语法补丁,才能实现7层过滤

安装补丁与l7过程:
Kernel Patch
tar zxvf linux-2.6.28.10.tar.gz -C /usr/src
tar zxvf netfilter-layer7-v2.22.tar.gz -C /usr/src
cd /usr/src
ln -sv linux-2.6.28.10 linux
cd /usr/src/linux
patch -p1 < ../netfilter-layer7-v2.22/kernel-2.6.25-2.6.28-layer7-2.22.patch
cp /boot/config-2.6.18-164.el5 /usr/src/linux/.config
make menuconfig
选择补丁项:
在networing support -> Networking options -> network packet filtering framework -> core netfiler configuration
选择如下:
<M> netfilter connection tracking support
<M> “layer7” match support
<M> “string” match support
<M> “time” match support
<M> “iprange” match support
<M> “connlimit” match support
<M> “state” match support
<M> “conntrack” connection match support
<M> “mac” address match support
<M> “multiport” multiple port match support
<M> FTP protocol support (NEW)

networking support -> networking options -> network packet filtering framework -> IP:netfiler configuration
选择如下:
<M> IPv4 connection tracking support (required for NAT)
<M> full NAT
<M> MASQUERADE target support
<M> NETMAP target support
<M> REDIRECT target support
选择完成之后执行如下:
screen # 打开一个新窗口,以避免更新内核阶段连接断开导致的升级终端
make # 编译开始后使用ctrl+a+d可以退出打开screen,但更新不断开
make modules_install # 安装内核模块
make install # 安装内核

vim /etc/grub.conf
将下面选项将1改为0即可
default=0

shutdown -r now # 重启生效
uname -r # 查看内核版本是否为新版本

编译新版本的iptabels:
Compiles iptabels:
cp /etc/init.d/iptabels ~/ # 备份iptables启动脚本到家目录
cp /etc/sysconfig/iptables-config ~/ # 备份配置文件到家目录
cp /etc/sysconfig/iptables ~/iptables.rules # 备份之前的策略到家目录
service iptables stop
rpm -e iptaebls-ipv6 iptables iptstate --nodeps # 卸载之前的安装
tar jxvf iptables-1.4.6.tar.bz2 -C /usr/src
cd /usr/src/iptables-1.4.6
cp ../netfilter-layer7-v2.22/iptables-1.4.3forward-for-kernel-2.6.20forward/libxt_layer7.* ./extension/
./configure --prefix=/usr --with-ksource=/usr/src/linux
make
make install
which iptabels # 查找一下安装路径
在/usr/sbin/iptables目录
vim ~/iptables # 更改一下启动脚本
将/sbin的安装目录路径全部更改为/usr/sbin,共3处
保存退出
mv ~/iptables /etc/rc.d/init.d/
chkconfig --add iptables
cp ~/iptables-config /etc/sysconfig/ # 配置文件恢复
cp ~/iptables.rules /etc/sysconfig/iptables # 恢复之前备份的iptables策略
安装协议特征包:此包用于识别xunlei、qq等应用特征码过滤的
tar zxvf l7-protocols-2009-05-28.tar.gz
cd l7-protocols-2009-05-28
make install
service iptables start

l7-filter uses the standard iptabels extension syntax
# iptables [specify table & chain] -m layer7 --l7proto [protocol name] -j [action]
l7所支持的协议可以再一下路径下查找:
cd /etc/l7-protocols/protocols/

写规则:172.16.100.7为外网地址,182.168.10.6为内网地址
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT --to-source 172.16.100.7 # 可访问互联网
iptables -A FORWARD -s 192.168.10.0/24 -m layer7 --l7proto qq -j REJECT # 拒绝内网访问qq
QQ:基于UDP协议,因此此规则执行后,已连接QQ的不会受影响,只针对新连接拒绝

时间过滤控制:
-m time:
--datestart --datestop
--timestart --timestop
--monthdays day
--weekdays day
--utc
例:拒绝上午8点10分到中午12点10分拒绝上互联网
iptables -A FORWARD -s 192.168.10.0/24 -m time --timestart 08:10:00 --timestop 12:10:00 -j DROP
# 下午14点半到18点20分禁止互联网
iptables -A FORWARD -s 192.168.10.0/24 -m time --timestart 14:30:00 --timestop 18:20:00 -j DROP
保存规则:
service iptables save
iptables-save > /etc/sysconfig/iptables.tus
iptables-restore < /etc/sysconfig/iptables.tus

iptables脚本:生效一套iptables的规则
#!/bin/bash
#
ipt=/usr/sbin/iptables
einterface=eth1
iinterface=eth0

eip=172.16.100.7
iip=192.168.10.6

$ipt -t nat -F
$ipt -t filter -F
$ipt -t mangle -F

$ipt -N clean_up
$ipt -A clean_up -d 255.255.255.255 -p icmp -j DROP
$ipt -A clean_up -j RETURN
# rules
$ipt -A
写好规则保存退出即可

POST-->MBR(bootloader)-->Kernel(initrd)-->init(/etc/inittab)
1、设定默认级别
2、系统初始化脚本
3、运行指定级别的服务
/etc/rc.d/rcN.d
S*
K*
S99local此文件链接到了/etc/rc.d/rc.local文件,也就意味着每次开机都会运行此脚本下的内容
vim /etc/rc.local # 也链接到/etc/rc.d/rc.local是同一个文件
/usr/local/sbin/ipt.sh # 如果这是iptabels生效规则的脚本,放在此处保存退出即可

IDS:入侵检测系统
nids:网络入侵检测系统
snort+iptables:入侵防御系统,发现供给后报警,关联iptables即可完成入侵防御
hids:主机入侵检测系统

xen,kvm:虚拟机也会自动创建iptables,以完成虚拟机之间网络规则防御

samba之一
Linux:
NFS(RPC:远程过程调用)
Windows:
CIFS:Common Internet File System,通用互联网文件系统
SMB:Service Message Block 服务信息块
NetBIOS(WINNS):网络输入输出系统
UNC:\\IP\Share_path\
映射网络驱动器
Linux/Uinx:
模拟一个NetBIOS和CIFS/SMB环境,来实现和windows之间的文件共享,实现工具就是Samba
还可以提供Winbind服务,让linux主机可以加入至windows的AD域的进程,需要结合LDAP(Openldap)

使用Samba必须开放端口:
NetBIOS:137/udp,138/udp
共享文件:139/tcp,445/tcp

挂载时使用本地服务器系统用户或其他服务器的用户认证,但Samba密码是单独存放的。

SMB安全级别:
user:默认级别
share:允许匿名访问
server:认证用户在其他服务器
domian:使用域账户的

安装配置samba:
yum list all samba*
rpm -e samba-client samba-common # 卸载系统自带版本
yum -y install samba3x samba3x-client samba3x-common
启动进程:
nmbd:提供NetBIOS
smbd:提供文件共享
winbindd:提供域服务
启动文件:/etc/rc.d/init.d/smb
配置文件:/etc/samba/smb.conf
主机解析:/etc/samba/lmhosts
存放smb用户文件:/etc/samba/smbusers

vim /etc/samba/smb.conf
注:#号;号均为注释,# 表示可以启用的参数或指令参数,;号纯注释信息
smb配置文件分几段:
Global Settings:全局配置
workgroup = MYGROUP
server string = Samba Server Version %v # 版本信息,%v为宏:变量,引用
netbios name = MYSERVER # 默认当前主机主机名第一段
interface = lo eth0 192.168.12.2/24 192.168.13.2/24 # 允许访问的网卡
hosts allow = 127. 192.168.12. 192.168.13. # 允许访问的网络
Logging Options:日志定义
log file = /var/log/samba/log.%m # 日志文件存放位置
max log size = 50 # 单位为KB,超出会滚动
Share Definitions:共享定义,用户家目录设置
[homes]
comment = Home Directories
browseable = no # 用户之外的无法访问
writable = yes # 用户是否具有写权限
; valid users = %S
; valid users = MYDOMAIN\%S
[printers]
comment = ALL Printers
path = /var/spool/samba
browseable = no
guest ok = no
writable = no
printable = yes
Domain Members Options:关于域成员用户配置
Standalone Server Options:单独服务器配置
security = user # 安全级别配置
passdb backend = tdbsam # 用户账户密码存放格式,tdb格式的sam
Browser Control Options:浏览控制选项,跟domain相关
Name Resolution:名称解析相关信息
wins support = yes # 是否支持wins服务
wins proxy = yes # 是否支持代理
Printing Options:打印机共享选项
load printers = yes # 是否加载打印机
cups options = raw # 使用哪种打印驱动程序共享,raw机制

主要参数:
[shared_name] # 共享名称,自定义
comment = # 共享的标注
path = # 共享路径
browseable = # 是否允许所有人浏览
public = # 是否允许所有人访问
read only = # 是否只读权限
writable = # 是否可写权限
write_list = user1,user2,@group,+group # 定义可写用户列表
valid_users = # 用户白名单,黑白名单同时存在时,白名单生效
invalid_users = # 用户黑名单

保存退出

testparm命令,专门测试samba配置文件有误错误内容

service smb start # 启动服务
getenforce # 确保selinux未开启

创建用户账号
useradd 2532:2532 eucalyptus # 先创建系统用户
smbpasswd -a eucalyptus # 将系统用户添加为smb用户,并设置密码
New SMB password: # 提示输入设置SMB密码
setfacl -m u:eucalyptus:rwx /share/test # 给用户更改权限

测试挂载:
\\172.16.100.1或者\\172.16.100.1\tools
提示输入账户密码,即可登录linux共享目录,创建一个文件,在linux的用户目录下查看是否写入

Windows共享目录给Linux
Windows上创建共享目录并设置共享,勾选网络共享选项
在Linux下使用smbclient:
-L NetBIOS_Name
-U username
-P password

smbclient -L 172.16.100.66 # 可直接查看对端共享列表
可以再windows端创建一个系统用户wuser创建密码
smbclient -L 172.16.100.66 -U wuser
输入密码
访问失败,报错(Called name not present)访问名称不存在
smbclient //172.16.100.66/test -U wuer
输入密码
smb:\>ls # 即可查看到挂载目录内容

smbclient //172.16.100.1/tools -U eucalyptus
输入密码
登录至linux的samba共享目录
smb:\>help # 即可查看到可以使用的命令
lcd:切换本地目录
put:上传单个文件
cd:切换对端目录
pwd:查看当前登录位置
!pwd:本地当前位置
!cd /home:本地切换到home目录,同lcd

使用mount也可以挂载smb共享目录:
mount -t cifs //172.16.100.1/tools /mnt -o username=eucalyptus
输入密码即可完成挂载
自动挂载,在fstab文件中
//172.16.100.1/tools /mnt cifs credentials=/etc/samba/cred.passwd 0 0
保存退出即可
credentials=/etc/samba/cred.passwd 需要创建此文件存放登录的用户密码信息
vim /etc/samba/cred.passwd
内容:
username=eucalyptus
password=redhat
保存退出
chmod og=--- /etc/samba/cred.passwd
umount /mnt
mount -a
查看是否挂载mnt目录

新建一个共享,共享名为tools,开放给mygrp中的所有用户具有读写权限,其他用户只有读权限;
[tools]
comment =
path =
guest ok = yes
write list = @mygrp

samba:基于IP的访问控制
iptabels:
TCP:139,445
UDP:137,138

samba:
hosts allow = 172.16. 127. # IP白名单

samba-swat
web GUI:基于web的图形配置界面

安装samba-swat:
yum -y install samba3x-swat

守护进程:
standalone
transient,瞬时守护进程,平时不启动,利用xinetd超级守护进程,来监听这些瞬时守护进程,有人访问瞬时进程时,先访问xinetd进程,然后启动瞬时进程,并转交给此进程,结束后关闭瞬时进程
chkconfig --list 查看进程列表时
xinetd base services: # 此项列表中的进程均为xinetd进程监听的所有瞬时进程
安装samba3x-swat之后
service xinetd start
在执行:
chkconfig swat on
service xinetd restart # 启动了swat服务,监听为tcp的901端口
另一种启动方法:
cd /etc/xinetd.d/
此目录下存放着所有xinetd相关进程
找到swat文件查看
将disable = no 并重启xinetd端口即可
文件中还定义了port端口号和协议类型等信息,wait选项表示否是接受多个用户同时访问,only_from是白名单,后面输入IP地址即可接受访问,user是允许的访问用户

使用浏览器访问172.16.100.1:901
用户名密码登录
status选项是服务状态,可以启动和停止Samba服务

tcp_wraper&xinetd

tcp_wraper:tcp层的访问控制工具
只对TCP的应用进行控制,依赖libwrap.so库文件
/etc/hosts.allow # 允许访问列表,tcp_wraper先检查allow文件,允许访问的直接放行
/etc/hosts.deny # 拒绝访问列表,allow匹配完检查deny,并拒绝
默认 # 以上均未匹配到则被允许
编写规则:
daemon_list: # daemon_list写的是进程可执行的二进制文件名称
如:sshd:192.168.0. # 允许或拒绝192.168.0段的地址sshd服务
vsftpd,sshd,in.telnetd: # 多个服务
ALL # 所有接受tcp_wraper的服务
daemon@host
如:vsftpd@192.168.0.186:1.0.0.0/255.0.0.0 # 允许或拒绝192.168.0.186的vsftpd访问1.0.0.0/255.0.0.0段
client_list[:Options]
如:IP # 使用单IP
network address # 使用单个IP地址
network/mask # 使用网络地址,只能使用长度格式,不能写为:1.0.0.0/8
172.16. # 使用IP段
HOSTNAME
fqdn # 域名解析
.a.org # 域名
MACRO # 宏
ALL # 所有来宾
LOCAL,KNOWN,UNKNOWN,PARANOID # 本地、可以正常解析的、无法解析的、正反向解析不匹配的
EXCEPT # 排除,不包含

ldd:显示共享库依赖关系。例如:ldd
ldd `which sshd` # 查看与sshd相关的库文件,其中就有libwrap.so.0文件
ldd `which httpd` # 查看没有与libwrap.so.0文件相关文件,因此httpd是不接受libwrap控制的
以上查找出的均为动态链接库

静态编译:也可以将库编译进某个程序
RPC服务依靠portmap
ldd `which portmap` # 查看虽然没有libwrap.so库,但不代表不支持
strings `which portmap` |grep hosts # 查看是否有静态编译的支持
/etc/hosts.allow # 允许访问列表
/etc/hosts.deny # 拒绝访问列表

xinetd:超级守护进程,需要关联运行级别,负责对瞬时守护进程的管理,是瞬时守护进程的代理人
ldd `which xinetd` # 也可以查到libwrap.so文件

服务分两类:进程可以在两类进程之间切换
standalone:独立守护进程
进程自己管理,响应速度快,但一直占用资源。
transient:瞬时守护进程,非独立守护进程
依赖于超级守护进程来代为管理,响应慢,但合理利用资源,偶尔连接的进程可以使用非独立的

sshd仅允许172.16.0.0/16网段访问;
方法:
1、/etc/hosts.allow # 先检查allow文件匹配到直接允许
sshd:172.16.

2、/etc/hosts.deny # 再检查拒绝为ALL,其他的网段均被拒绝
sshd:ALL

telnet仅不允许172.16.0.0/16网段访问,但允许172.16.100.200访问,其他客户端不做控制;
方法1:
1、/etc/hosts.allow
in.telnetd:172.16.100.200

2、/etc/hosts.deny
in.telnetd:172.16.

方法2:
1、/etc/hosts.deny
in.telnetd:172.16. EXCEPT 172.16.100.200

方法3:
1、/etc/hosts.allow
in.telnetd:ALL EXCEPT 172.16. EXCEPT 172.16.100.200

2、/etc/hosts.deny
in.telnetd:ALL

client_list[:Options]
/etc/hosts.allow
in.telnetd:172.16. :DENY # Options的用法,在最后可以定义决绝还是允许
/etc/hosts.deny
in.telnetd:ALL :ALLOW

spawn:表示启动
/etc/hosts.allow
in.telnetd:172.16. :spawn echo " somebody entered,`date` " >> /var/log/tcpwraper.log # 触发日志记录

tcp wrapper macro:tcp wrapper使用的宏
%c:client infomation (user@host)
%s:service info(server@host)
%h:client hostname
%p:server PID

# man 5 hosts_access # 可以通过此命令查询tcp_wraper宏的使用方式
/etc/hosts.allow
in.telnetd:172.16. :spawn echo " `date`, Login attempt from %c to %s " >> /var/log/tcpwraper.log # 附加的内容中不能使用冒号:

xinetd:超级守护进程,需要关联运行级别,负责对瞬时守护进程的管理,是瞬时守护进程的代理人
/etc/xinetd.conf # 配置文件,可管理N个非独立进程
/etc/xinetd.d/* # 被拆分后的非独立进程的配置文件存放位置

/etc/xinetd.conf配置文件主要有两部分:
1、全局配置(服务的默认配置)
2、服务配置
service <serivce name>
{
<attribute(属性)> <assign_op(赋值操作符)> <value(值)> <value> ...
...
}

注解:
service telnet
{
disable = no # 服务启动还是关闭
flags = REUSE # 默认为REUSE,表示重用,重复启用
socket_type = stream # 表示TCP协议,dgram表示udp
wait = no # 一个用户在访问时另一个用户是否等待,此处表示不用等待
user = root # 运行此服务的用户
only_from = 172.16.0.0/16 # 仅允许此网段的IP访问
bind = 172.16.100.1 # telnet监听仅通过某个IP地址访问23端口
access_times = 10:00-14:00 # 仅允许10点到14点之间访问
cps = 2 10 # 最大连接数1个,高于2个的请求禁止10秒钟
per_source = 1 # 每一个IP允许最大并发连接数
instances = 50 # 本服务的最大连接数
server = /usr/sbin/in.telnetd # 定义应用程序是哪个文件启动
log_type = FILE /var/log/telnet.log # 自定义日志格式和位置
log_on_failure += USERID # 失败时记录日志格式,+=表示默认值基础上增加的项,还可以-=表示在默认项中移除哪项
}

日志通常会记录在/var/log/messages中,也可以自定义位置和格式

xinetd访问控制:
only_from = :是白名单
IP:172.16.100.200
NETWORK:172.16.0.0/16 172.16.0.0/255.255.0.0
HOSTNAME:FQDN
DOAMIN:.magedu.com

no_access = :仅拒绝访问,最好不要与only_from同时使用,如一起使用匹配最小范围生效。

时间控制:
access_times = hh:mm-hh:mm : 使用时间控制访问
hh:0-23
mm:0-59

监听的地址(提供服务的地址):
bind = :绑定在哪个地址
interface = :绑定在哪个网卡

资源访问控制:
cps = :限制每秒钟访问的个数。第一个表示每秒钟入站最大连接数,第二个如果高出第一个值,需要禁用的时间,以秒为单位。默认第一个50,第二个为10.
per_source = :同一个IP地址允许访问的最大并发连接数
instances = :定义本服务的最大连接数

默认访问控制参数:
server = :指定启用此服务的二进制进程文件
server_args = :向启动的server传递参数
banner = :欢迎标语,指定某个文件的内容为登录后显示的标语
port = :自定义端口号


SYSLOG:专门用于记录日志的服务(syslogd,klogd)


nss&pam:用户认证

Authentication:认证,验证一个用户身份的手段
md5:/etc/shadow
mysql
ldap
nis
kerberos
Authorization:授权,一个用户是否被允许访问一个服务或资源的过程

名称解析:用户熟悉的字符串转换为系统识别的标识
username-->UID
groupname-->GID
FQDN-->IP
http-->80

FQDN-->IP
dns
/etc/hosts
mysql
nis
ldap:轻量级目录访问协议,比mysql查询速率高很多

系统登录程序login:
内置/etc/passwd进行用户账户ID号对应,但是过于庞大的系统用户群此方式效率会慢很多

APP-->nsswitch-->resolve_lib
nsswitch
/etc/nsswitch.conf # 配置文件
写法:passwd:file # 后面指定的file就是对应要去哪里查找的对应文件或方法
group:file
hostname:file dns # 也可以写多种
service nisplus [NOTFOUND=return] files # 另一种写法,表示查找后的返回机制。此句表示,如果nisplus查找service服务服务正常单无对应名称,则返回信息,其他的情况,则到files中查找
SUCCESS:服务正常,找到名称,正常转换
NOTFOUND:服务正常,无对应名称
UNAVAIL:服务不可用
TRYAGAIN:服务出现临时性故障
return:是一种执行机制和动作,否则就继续。

/etc/protocols # 存放常用协议以及端口号对应关系的存储文件
/etc/services # 也存放着各服务对应的协议端口

getent命令:从管理库获得条目内容
getent passwd # 直接获取/etc/passwd文件中内容。与cat类似

名称解析完成后需要验证用户机制:
认证过程:
APP--> username:password
root-->nsswitch.conf-->passwd:files
'123456'-->nsswitch.conf-->shadow:files
auth:123456-->md5(salt)-->compare(比对) 通过比对核实之后认证通过,完成认证过程
认证本身也可以不用借助名称解析服务去查找用户原来存放的密码

PAM:Pluggable Authentication Modules:可插入式认证模块,是一个框架,不做任何认证工作,需要依靠lib库文件完成认证
64位系统库文件在:/lib/security,/lib64/security两个目录中
pam_unix.so文件实现用户密码比对
/etc/pam.d/login # 完成login系统用户认证过程的配置文件

首先是pam认证中的四种认证站stack:
auth类型:用户输入的用户密码是否匹配
account类型:审核用户账号是否依然有效,与auth结合使用
password类型:用户修改密码时,审核用户密码的合规性等信息
session类型:定义用户登录后的会话属性内容,如可登录多长时间等

/etc/pam.d/service:service表示服务名
格式:
type:类型
auth类型:用户输入的用户密码是否匹配
account类型:审核用户账号是否依然有效,与auth结合使用
password类型:用户修改密码时,审核用户密码的合规性等信息
session类型:定义用户登录后的会话属性内容,如可登录多长时间等
control:控制,某类型出现多次如何相互作用
required:必须符合的条件,一票否决权,如果不过继续后面的条件匹配
requisite:必须符合条件,绝对意义上的一票否决,如果不过,无需匹配后面的条件
sufficient:充分条件,此条通过完成认证过程,无需后面的检查。一票通过权
optional:补充可选条件
include:映射到其他文件,由另外的文件进行条件匹配
审核回值:
ok:此模块通过,继续下一条检查
done:一票通过,最终结果通过
bad:审核失败,继续下一条检查
die:结果失败,无需下面的检查,直接拒绝,一票否决权
ignore:忽略,无决定结果
reset:忽略此前的审核结果,从这里重新开始
格式:
required [success=ok new_authtok_reqd=ok ignore=ignore default=bad]
requisite [success=ok new_authtok_reqd=ok ignore=ignore default=die]
sufficient [success=done new_authtok_reqd=done default=ignore]
optional [success=ok new_authtok_reqd=ok default=ignore]

module-path [module-arguments]:模块路径及模块参数,后面的模块参数并非必须
pam_unix:使用md5的方式校对认证,相同通过不同拒绝
options:
nullok:允许密码为空,空也ok
shadow:用户密码认证在shadow中校对
md5:使用md5方式的加密方式
try_first_pass:输入此前输入过的密码,能够通过即可
use_authtok:当密码修改时要求密码设置为此项可通过的密码
pam_permit:允许访问
pam_deny:拒绝访问,通常用在other中
pam_cracklib.so:检测是否在密码字典中存在,密码安全性检测模块
minlen:最短长度
difok:密码是否与之前相同
dcredit=N:包含至少几位数字
ucredit=N:包含至少几位大写字母
lcredit=N:包含至少几位小写字母
ocredit=N:包含至少几位特殊字符
retry=N:最多尝试多少次
pam_shells:用户登录时必须使用/etc/shells存在的shell
pam_securetty:限定管理员只能在限定设备登录,必须使用/etc/securetty内允许的tty类型
pam_listfile:到某个文件中验证用户登录是否合法
item=[tty|user|rhost|ruser|group|shell] # 定义文件以哪种类型取值
sense=[allow|deny] # 在这个文件中的类型拒绝或允许
file=/path/filename # 指定文件
onerr=[succeed|fail] # 一旦发生错误,指定success还是fail
[apply=[user|@group]] # 属于文件中的用户和组可以允许登录
[quiet]
pam_rootok:root用户直接通过
pam_limits:资源限定控制
/etc/security/limits.conf
格式:
<domain> <type> <item> <value>
<domain>:指定范围
username
group
通配符*或%
<type>:类型
soft:软限制
hard:硬限制,只有管理员可调整硬限制
<item>:限制规则
core:所能够打开核心文件的size KB单位
nofile:所能打开的最大文件个数
rss:所能使用的最大内存集KB单位
as:地址空间限制
cpu:所能使用的最大cpu时间,单位分钟
nproc:用户能运行的进程最大个数
<value>:限制值
如:
* soft core 0 # 所有对象软限制core打开限制为0KB
@student - maxlogins 4 # student组软硬类型最大登录次数为4
/etc/security/limits.d/* # 这些文件都可以完成限定
pam_env:设置或撤销环境变量
/etc/security/pam_env.conf配置文件中设定
pam_wheel:设置限定哪些用户可以su到root用户,启用功能后只有wheel组才可su
pam_time:根据时间限定登录
login;tty*&!ttyp*;!root;!AL0000-2400 # servicename 指定终端 指定用户 指定时间段
时间表示WD表示工作日,WK表示周末,时间之间可以用|隔开,表示多个时间段

/etc/pam.d/other文件:定义默认规则的文件,无对应服务配置文件时以此文件定义为准


cat /etc/pam.d/system-auth-ac :认证机制type和control配置文件

bash编程系列之数组

变量:内存空间,字符

array:数组,既变量的集合
element:数组元素,没个数组中去某个变量
tndex:索引,每个元素的数字编号,从0开始编号
例如:${AA[0]} 表示一个属组中第一个元素

使用生命一个数组:
赋值方法1:
declare -a AA
AA[0]=jerry
AA[1]=tom
AA[2]=wendy
AA[6]=natasha # 表示有7个元素,其中3-5位空
赋值方法2:
AA=(jerry tom wendy)
AA=([0]=jerry [1]=tom [2]=wendy [6]=natasha)
AA[3]=selina # 想补全3-5的空缺可以直接添加引用即可
AA[4]=nikita

脚本示例:
vim testarray.sh
#!/bin/bash
#
AA=([0]="jerry" [1]="tom" [6]="nikita") # 预防数组元素中出现空格等特殊字符最好用""号括起来

echo ${#AA[0]} # 表示AA数组中的第0个元素的字符个数,也就是jerry字符数5,如果不输入[0],默认显示的也是第一个元素的字符数

echo ${#AA[*]} # 引用整个数组当中值不为空的元素的个数
echo ${#AA[@]} # 引用整个数组当中值不为空的元素的个数

for I in {1..20}; do # 连续取值20次
INDEX=$[$RANDOM%7] # 数组中的6个赋值中随机选一个0-6之间的值,此句为对7其余
echo ${AA[$INDEX]} # 输出随机取值,输出大部分为空,偶尔会出现tom或jerry和nikita
done
echo ${AA[0]}
echo ${AA[6]}
echo ${AA[2]} # 输出结果为空,因为未给2赋值

写一个脚本:随机从人员中选择5位回答问题。
vim
#!/bin/bash
#

写一个脚本:找出一组数据中的最大数,这组数据用数组保存
vim findmax.sh
#!/bin/bash
#
for I in {1..10}; do
ARRAY[$I]=$RANDOM # 随机生成10个随机数
sleep 1 # 间隔1秒,生成一个数
echo -n "${$ARRAY[$I]}" # 输出随机生成的数值,-n为不换行输出
done
echo # 此处的echo是让脚本换行显示,否则会将最大的放在上一行连接在一起
ARRAY=(34 73 25 91 49 25 75 133 92 951) # 也可以正常输入,生成一组数组
declare -i MAX=${ARRAY[0]} # 生命变量为第一个元素
INDEX=$[${#ARRAY[*]}-1] # 将数组中元素个数引用到INDEX变量
for I in `seq 1 $INDEX`; do # 循环执行从1到数组个数的次数
if [ $MAX -lt ${ARRAY[$I]} ]: then # 依次对比第一个元素到最后一个元素的数值
MAX=${ARRAY[$I]} # 取出最大的赋值到MAX变量
fi
done

echo $MAX # 输出MAX变量查看是否为最大值951

保存退出


写一个脚本:生成一个数组
1、数组的元素个数为1-39
read
2、数组元素值不能相同

3、显示此数组各元素的值

vim creatarray.sh
#!/bin/bash
#
read -p "The element numbers[1-39]:" ELENUM
declare -a ARRAY
function COMELE {
for J in `seq 0 $[${#ARRAY[@]}-1]`; do
if [ $1 -eq ${ARRAY[$I]} ]; then
return 1
fi
done

return 0
}

for I in `seq 0 $[$ELENUM-1]; do
while true; do
ELEMENT=$[$RANDOM%40]
COMELE $ELEMENT
if [ $? -eq 0 ]; then
break
fi
done
ARRAY[$i]=$ELEMENT
echo "${ARRAY[$I]}"
done
保存退出

trap:在脚本中捕捉信号,并且可以待定处理
信号:
1:SIGHUP
2:SIGINT
9:SIGKILL # 不允许捕捉
15:SIGTERM # 不允许捕捉
18:SIGCONT
19:SIGSTOP

捕捉信号方法:
trap命令
样例:trap '处理操作' SIGINT
如:trap 'echo "No quit..."' INT # 拒绝ctrl+c终端信号操作并提示No quit...

vim traptest.sh
#!/bin/bash
#
trap 'rm -rf /var/tmp/test;echo "clean...";exit 5' INT
mkdir -p /var/tmp/test
while true; do
touch /var/tmp/test/file-`date +%F-%H-%M-%S`
sleep 2
done
保存退出
一旦未写exit 5 之类的退出命令,则会循环执行无法退出,此时需要执行kill %1来终止脚本

bash脚本编程之在bash脚本中使用选项
为脚本写好标头,并在写每个新脚本中套用
vim mkscript
内容如下:
#!/bin/bash
# Name:mkscript
# Descriprion:Create script
# Version:0.0.1
# Author:magedu
# Datetime:
# Usage:mkscript FILENAME
while getopts ":d:" SWITCH; do # 将mkscript脚本加一个-d选项,后跟参数,参数内容可以写脚本简介
case $SWITCH in
d)
DESC=$OPTARG ;;
\?)
echo "Usage:mkscript [-d DESCRIPRION] FILENAME"
esac
done
shift $[OPTIND-1] # OPTIND选项索引,依次指向第一个参数,减1就将选项去掉一个
if ! grep "[^[:space:]]" $1 &> /dev/null; then
cat > $1 << EOF
#!/bin/bash
# Name:`basename $1`
# Descriprion:$DESC
# Version:0.0.1
# Author:magedu
# Datetime:`date '+%F %T'`
# Usage:`basename $1`

EOF
fi

vim + $1

until bash -n $1 &> /dev/null; do
read -p "Syntax error, q|Q for quiting, others for editing:" OPT
case $OPT in
q|Q)
echo "Quit."
exit 8 ;;
*)
vim + $1
;;
esac
done

if ! bash -n $1 &> /dev/null; then
vim + $1
fi

chmod +x $1
保存退出
chmod +x mkscript
每次新建脚本时使用
./mkscript test.sh
即可直接进入编辑模式,并且写好标头内容
cp mkscript /bin 拷贝到bin目录下即可当作命令使用创建脚本

getopts命令使用:
mkscript opttest.sh
除了标头内容添加:
getopts ":b:d:" OPT # 定义了b和d为选项,加冒号可以对应$OPTARG参数的输出,不加冒号只代表选项;在所有选项前面加:号是不输出所有错误信息;
echo $OPT # 输出选项
echo $OPTARG # 输出选项后面的参数

两个选项都可以使用的方式编写:
USAGE() {
echo "Usage: optitest.sh [-d argu] [-b argu]"
}
while getopts ":b:d:" SWITCH; do
case $SWITCH in
b) echo "The option is b." ;;
echo $OPTARG ;;
d) echo "The option is d." ;;
echo $OPTARG ;;
\?) echo USAGE ;;
esac
done

写一个脚本getinterface.sh,脚本可以接受选项(-i -I -a),完成以下任务
使用以下形式,getinterface.sh [-i interface|-I IP|-a]
用户使用-i时,显示其指定的网卡的IP地址,-I时,显示其后面的IP地址所属的网络接口卡,-a时全部显示

mkscript -d "Get ethernet information" getinterface.sh

#!/bin/bash
# Name:getinterface.sh
# Descriprion:Get ethernet information
# Version:0.0.1
# Author:magedu
# Datetime:
# Usage:getinterface.sh

SHOWIP() {
if ! ifconfig | grep -o "[^[:space:]]\{1,\}" | grep $1 &> /dev/null; then
return 13
fi

echo -n "${1}:"
if ! ifconfig $1 |grep "inet addr:[0-9\.{1,\}]" |cut -d: -f2
}

SHOWETHER() {
if ! ifconfig|grep -o "inet addr:[0-98\.]\[1,\]"|cut -d: -f2 | grep $1 &> /dev/null; then
return 14
fi
echo -n "${1}:"
ifconfig |grep -B 1 "$1" | grep -o "^[^[:space:]]\{1,\}"
}

USAGE() {
echo "getinterface.sh <-i interface|-I IP>"

while getopts ":i:I:" SWITCH; do
case $SWITCH in
i)
SHOWIP $OPTARG
[ $? -eq 13 ] && echo "Wrong ehtercard."
;;
I)
SHOWETHER $OPTARG
[ $? -eq 13 ] && echo "Wrong IP."
;;
\?)
USAGE ;;
esac
done

保存退出

当前主机所有IP地址取出:
ifconfig|grep -o "inet addr:[0-98\.]\[1,\]"|cut -d: -f2

配置使用vnc服务
明文传输,互联网慎用
rpm -qa vnc* # 检查vnc安装情况,有vnc-server包即可

vnc的密码非shadow文件中,因此设定vnc密码需要使用vncpasswd设定
vncpasswd
Password:输入新密码
Verify:再次输入
service vncserver start # 启动vnc服务,第一次启动时不建议使用此命令
第一次启用vncserver建议使用以下命令
vncserver &
稍等片刻会有反馈信息,提示使用:#数字来连接,启动第一次就生成:1,表示生成第一个桌面,再次执行返回:2,客户端连接哪个桌面就写入:#即可
客户端:
VNC viewer程序安装之后启动
在打开界面中服务器输入 172.16.100.1:1 输入密码即可登录

twm:窗口管理器
配置使用gnome桌面
vncserver启动之后会在当前目录下生成一个.vnc的目录
cd .vnd
vim xstartup # 编辑xstartup文件
在最后一行
twm & 替换成 gnome-session &
并将一下两行取消注释
unset SESSION_MANAGER
exec /etc/X11/xinit/xinitrc
保存退出
重启vncserver
service vncserver restart # 此命令不建议,可能不会生效
使用以下命令先杀掉当前连接:
vncserver -kill :2
vncserver -kill :1
然后再启动
vncserver &
此时打开的界面就是REDHAT完全的图形化界面了

mysql系列之一关系型数据库基础理论
MySQL
SQL\MySQL
事务,隔离,并发控制,锁
用户和权限
监控
STATUS
索引类型:查询
VARIABLES
备份和恢复
复制功能
集群

文件数据弊端:
数据冗余和不一致性
数据访问困难
数据孤立
完整性问题
原子性问题
并发访问异常
安全性问题
DBMS
层次模型
网状模型
关系模型
RDBMS

文件数据层次:
表示层
文件
逻辑层
文件系统:存储引擎
物理层
元数据
数据:数据块

关系模型(结构化数据模型):
关系模型
实体-关系模型
对象关系模型:基于对象的数据模型
半结构化数据模型:XML(扩展标记语言)
将每个属性标记出来,避免一张表内出现不同标记的内容
<name>Jerry</name>
<age>50</age>

关系:代数运算
交集;一组实体的组合
并集:属于A或者属于B
差集:属于A但不属于B
全集:所有实体的组合
补集:全集减去集合剩余内容

SQL:Structure Query Language结构化查询语言

70年代IBM公司开发出System R:SQL第一款关系型数据库
Ingres,伯克利分校开发的关系型数据库
Oracle,Sybase等相继面世

ANSI:SQL标准,美国国家标准委员会制定,ansi-sql

sql86,sql89,sql92,sql99均为标准,以年份命名

DML:数据操作语言
增删查改
INSERT
DELETE
SELECT
UPDATE
DDL:数据定义语言
RDB对象:
库、表、索引、视图、用户、存储过程、存储函数、触发器、事件调度器
CREATE
DROP
ALTER
约束:保障数据完整性,定义有效数据范围
域约束:数据类型约束,必须符合数据类型
外键约束:引用完整性约束,需要另外一张表约束主表数据插入是否是合规数据的
主键约束:某字段能唯一标识此字段所属的实体,并且不允许为空
一张表只能有一个主键
唯一性约束:每一行的某字段都不允许出现相同值,可以为空
一张表中可以有多个唯一键
检查性约束:自定义某键的取值范围,保障不出现违反常理的数据
mysql对检查性约束能力有限,Oracle与SQL Server功能较全
constraint
DCL:数据控制语言
定义数据的访问权限
GRANT
REVOKE

关系型数据层次:
表示层:表
逻辑层:存储引擎,解构
物理层:数据文件

数据存储和查询
存储管理器
权限及完整性管理:违反约束的不能操作数据
事务管理器:处理数据存储读取一致性等操作,保障原子性
文件管理器:将表数据保存在磁盘分区上,并维护管理这些对应关系
缓冲区管理器:负责将表的热数据从硬盘读取到内存中
查询管理器
DML解释器:理解DML表示意思
DDL解释器:
查询执行引擎

mysql:单进程
多线程
守护线程
应用线程
线程重用,thread reuse
缓存数据优化

32bit操作系统:
最大4G空间
内核占用1G
有效使用只有2.7G,mysql一个表可能就会占满
因此mysql服务器必须使用64位系统
SMP:对称多处理器,mysql对此功能支持很差,一个查询只能在一个CPU执行
但可以用多个服务器进行集群式的解决方案,因此SMP也不是mysql发展的瓶颈

连接mysql的方式和处理过程:
应用程序,DBA,API,查询工具
以上接口接入查询管理器
查询管理器转存到存储管理器

关系运算:
投影:只输出指定属性
选择:只输出符合条件的行,WHERE
自然连接:具有相同名字的属性上所有取值相同的行
笛卡尔积:(a+b)*(c+d)=ac+ad+bc+bd,将表的每个值与另一表的值相关联结果
并:集合运算

SQL查询语句:
sequel,早期叫法,后期改名为SQL

SQL语言的组成部分:
DDL
DML
完整性定义语言:DDL的一部分功能
视图定义语言:
事务控制语句
嵌入式SQL和动态SQL:需要其他语言配合完成
授权:DCL

使用程序设计语言如何跟RDBMS交互:
嵌入式SQL:与动态SQL类似,但其语句必须在程序编译时完全你确定下来;并由预处理器完成处理;
ODBC:比JDBC底层的多,嵌入的是ODBC内置查询逻辑
动态SQL:程序设计语言使用函数(mysql_connect())或者方法与RDBMS服务器建立连接,并进行交互;通过建立的链接向SQL服务器发送查询语句,并将结果保存至变量中,而后进行处理;
JDBC:Java服务器与SQL服务器的接口

MySQL处理过程:
连接管理器:用于接受用户请求并转交解析器
1、连接管理器:监听端口套接字
2、线程管理器:为用户分配响应线程
3、用户模块:管理用户是否能够连接请求,验证用户身份
4、命令分发模块:将不同的命令分发不同的解析器中去
与缓存器交互
完成日志记录
解析器:词法分析,语法分析处理,生成解析树,转交热数据给缓存器,非热数据转交给优化器
1、select语句交给优化器
2、update、insert、delete语句交给表定义模块
3、修复模块:repair命令修复表中某些逻辑错误
4、状态报告模块:执行反馈表中某些状态反馈
5、复制模块:完成数据主从复制过程
6、访问控制模块:检查用户特定操作是否有相应操作权限
7、表管理器:负责创建读取或修改表定义文件;完成最终操作,交给存储引擎,也是存储引擎的接口
表结构定义:专门有表结构定义文件来保存表结构
维护表描述符高速缓存
管理表锁
表修改模块:表删除,重命名,移除,更新,插入等操作
表维护模块:检查,修改,备份,恢复,优化(碎片整理)及解析;
缓存器:缓存热数据,有结果直接返回结果
优化器:优化MySQL语句,优化解析器提供的语言路径
存储引擎:将物理逻辑转换为表示逻辑
插件式存储引擎:可以根据不同数据类型选择不同的存储引擎
5.5.8之前:默认MyISAM,不支持事务,性能较好,用于查询多修改少的场景,例如数据仓库
5.5.8之后:默认InnoDB,支持事务,极其接近Oracle机制,适用于在线事务处理系统

行:定长,变长
文件中记录组织:
堆文件组织:一条记录可以放在文件中的任何地方;
顺序文件组织:根据“搜索码”索引字段值为序进行存放;
散列文件组织:

表结构定义文件,表数据文件

表空间:table space,多个表的数据存储在一个数据文件

数据字典:Data Dictionary,默认在mysql初始化完成后,有个mysql库就是mysql的数据字典
关系的元数据
关系名
字段名
字段的类型和长度
视图
约束
用户名,权限,密码

缓冲区管理器:
缓存置换策略
被钉住的块:不允许被置换的块

mysql系列之三MySQL数据库基础及编译安装
Alpha:内测版
Beta:公测版
RC(Release Candidate):发行候选版
GA(General Availablility):正式版

MySQL产品组成
MySQL Server(mysqld服务端,mysql客户端)
MySQL Cluster:mysql集群性能非常好,至少需要4个节点组成,数据在内存中处理不丢失,5个9的标准;但是很少商业使用,均使用第三方插件进行集群配置。
MySQL Proxy:代理,前段不处理按需转发至后端处理,读写分离场景使用,可以重写sql语句
MySQL Adminitrator:可视化管理工具
MySQL Query Browser:查询浏览器
MySQL Workberch:数据库设计工具,已和以上两个工具整合在一起
MySQL Migration Toolkit:移至工具箱,实现不同平台和版本的sql数据导入导出的工具
MySQL Embedded Server:嵌入式环境专用工具
MySQL Drivers and Connectors:驱动和连接器工具

MySQL:商业版和社区版

MySQL
MariaDB:MySQL被收购后,作者又开发的新的开源的MySQL数据库
Percona:MySQL性能优化站点,发布大量MySQL优化文章

安装MySQL介绍:
专用软件包管理器包
deb,rpm:RHEL(Oracle Linux),CentOS,SUSE
通用二进制格式包
gcc编译,GUN编译,x86,x64
icc编译,Intel编译
源代码包:
5.5之前版本用make编译
5.5版本开始使用cmake编译,但是再RHEL5之前的版本没有cmake工具需要安装,6以后版本全部支持

MySQL安装后的目录结构:
bin:二进制执行程序,服务端以及客户端
data:数据目录
include:头文件
lib:库文件
man:帮助文档
mysql-test:测试组件
scripts:初始化脚本目录
share:错误信息的不同语言版本支持
sql-bench:基准性能测试工具包
support-files:脚本,启动服务脚本等等

MySQL读取配置文件在UNIX系统中启动过程:
启动时:/etc/my.cnf
然后:/etc/mysql/my.cnf
然后:$MYSQL_HOME/my.cnf
然后:/path/to/file when defaults-extra-file=/path/to/file is specified :即指定
最后:~/.my.cnf
以最后一次读取的配置为最终生效的结果。按次序第一次读取的反而优先级低
MySQL在Windows中加载顺序:
启动时:%WINDIR%\my.ini,%WINDIR%\my.cnf
然后:C:\my.ini,C:\my.cnf
然后:%INSTALLDIR%\my.ini,%INSTALLDIR%\my.cnf
最后:/path/to/file when default-extra-file=/path/to/file is specified:即自定义

安装完成后操作:
安装完成之后会有5个用户:
三个root用户:root@127.0.0.1,root@localhost,root@hostname 默认没密码,为用户加密
1、# mysqladmin -u USERNAME -h HOSTNAME password 'NEW_PASS' -p
2、mysql>SET PASSWORD FOR 'USERNAME'@'HOST'=PASSWORD('new_pass');
3、mysql>UPDATE mysql.user SET PASSWORD=PASSWORD('new_pass') WHERE CONDITION;
mysql>privileges;
两个匿名用户:''@localhost,''@hostname 匿名用户尽量删除
drop user ''@localhost; # 删除匿名用户

MySQL安装:
源码安装MySQL
安装cmake
tar xf cmake-2.8.8.tar.gz
./bootstrap
make
make install
安装mysql-5.5.25a
使用cmake编译mysql-5.5
cmake指定编译选项的方式不同于make,其实现方式对比如下:
./configure cmake .
./configure --help cmake . -LH or ccmake .
指定安装文件的安装路径时常用的选项:
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql
-DCMAKE_DATEDIR=/data/mysql
-DSYSCONFDIR=/etc
默认编译的存储引擎包括:csv、myisam、myisammrg和heap,若要安装其他存储引擎,可以使用类似如下的编译选项:
-DWITH_INNOBASE_STORAGE_ENGINE=1 # 使用innoDB存储引擎,必须加载
-DWITH_ARCHIVE_STORAGE_ENGINE=1 # ARCHIVE存储引擎,推荐加载
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 # 黑洞存储引擎,推荐加载
-DWITH_FEDERATED_STORAGE_ENGINE=1 # 联合存储引擎,5.5不支持

若要明确指定不编译某存储引擎,可以使用类似如下的选项:
-DWITHOUT_<ENGINE>_STORAGE_ENGINE=1
比如:
-DWITHOUT_EXAMPLE_STORAGE_ENGINE=1 # 不加载某个存储引擎
-DWITHOUT_FEDERATED_STORAGE_ENGINE=1
-DWITHOUT_PARTITION_STORAGE_ENGINE=1

如若要编译进其他功能,如SSL等,则可使用类似如下选项来实现编译时使用某库或不适用某库:
-DWITH_READLINE=1 # 支持批量导入mysql数据的功能
-DWITH_SSL=system # 支持SSL会话,复制功能使用
-DWITH_ZLIB=system # 压缩库
-DWITH_LIBWRAP=0 # TCP-wrap提供访问控制

其他常用的选项:
-DMYSQL_TCP_PORT=3306 # 默认端口
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock # 默认套接字文件路径
-DENABLED_LOCAL_INFILE=1 # 是否启用local_infile
-DEXTRA_CHARSETS=all # 是否支持其他字符集
-DDEFAULT_CHARESET=utf8 # 默认启用位长
-DDEFAULT_COLLATION=utf8_general_ci # 默认排序规则,与字符集相匹配
-DWITH_DEBUG=0 # 不启用debug模式
-DENABLE_PROFILING=1 # MySQL性能分析

注解:字符集:定义01代码与字符之间的对应关系,中文字符集:GBK,GB2312,GB10030,UTF8等
排序规则:不同字符集的排序方式不同,因此需要按照不同字符集定义不同的排序方式

如果详情里此前的编译所生成的文件,则需要使用如下命令:
make clean
rm CMakeCache.txt

正式安装mysql:
groupadd -r msyql
useradd -g mysql -r -d /data/mydata mysql
tar xf mysql-5.5.25a.tar.gz
cd mysql-5.5.25a
cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYQL_DATADIR=/data/mydata \
-DSYSCONFDIR=/etc \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_READLINE=1 \
-DWITH_SSL=system \
-DWITH_ZLIB=system \
-DWITH_LIBWRAP=0 \
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock \
-DDEFAULT_CHARESET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci
make
make install

chown -R :mysql /usr/local/mysql # 改属组为mysql
cd /usr/local/msyql
scripts/mysql_install_db --user=mysql --datadir=/mydata/data
cp support-files/my-large.cnf /etc/my.cnf
cp support-files/mysql.server /etc/init.d/mysqld
chkconfig --add mysqld
chkconfig mysqld on
service mysqld start
vim /etc/profile.d/mysql.sh
内容:
export PATH=$PATH=/usr/local/mysql/bin
保存退出
sh /etc/profile.d/mysql.sh
echo $PATH
mysql 直接登录
msyql>show databases; # 查看库
mysql>show engines; # 查看存储引擎
mysql>DROP USER ''@localhost;
mysql>DROP USER ''@localhost.localdomain; # 删除两个匿名用户
mysql>UPDATE user SET Password=PASSWORD('redhat') WHERE user='root'; #root用户加密
vim /etc/my.cnf
datadir = /mydata/data

mysql客户端与服务器通信过程:
同一Unix主机:
通过mysql.sock完成进程间通信
同一台Windows主机:
通过memory(pipe)内存或管道方式通信
不同主机:
TCP/IP协议通信

mysql架构:
mysql服务端程序,对应配置文件中[server]内定义的内容
mysqld服务端程序
mysql客户端程序,对应配置文件中[client]内定义的内容
-u USERNAME
-h HOST
-p 'PASSWORD'
--protocol
tcp
socket # 默认使用socket
pipe # win使用
memory # win使用
--host # 指定主机
--port # 指定端口
--shared-memory-base-name
--socket # 指定套接字
mysql:客户端主进程
mysqlimport:
mysqldump:数据库备份程序
mysqladmin:管理工具
mysqlcheck:检查数据库完整性工具
mysql非客户端程序
myisamchk:检查和修复myisam表
myisampack:压缩myisam表

数据目录下内容介绍:
cd /mydata/data/mysql
有很多数据库文件
db.opt文件存放的是数据库默认的字符集与排序规则
MyISAM:
.frm:表结构定义
.MYD:表数据
.MYI:表索引
InnoDB:
所有表共享一个表空间文件:
建议:每表一个独立的表空间文件,默认不打开此特性
.frm:表结构
.ibd:表空间(表数据和表索引),创建之初有初始数据
打开方式:
mysql>SHOW VARIABLES LIKE '%innodb%'; # 查看所有与InnoDB相关选项
innodb_file_per_table选项,默认为OFF改为ON,但临时生效
或者编辑配置文件:
vim /etc/my.cnf 永久生效
在[mysqld]中加入:
innodb_file_per_table = 1
重启mysql数据库服务

mysql系列之四mysql客户端工具的使用
mysql
--user,-u
--host,-h
--password,-p
--port
--protocol
--database SATABASE, -D
mysql>
交互式模式
mysql>\? # 查看交互式命令的使用方式
source或者\. 后跟指定的sql脚本 可以批量导入执行sql语句
批处理模式(脚本模式)
# mysql -uroot -ppassword < /root/init.sql

mysql>
命令两类:
客户端命令
clear或\c:提前终止语句执行,命令输入一半取消直接输入\c即可,结束符之前输入
connect或\r:连接到服务器
ego或者\G:代替结束符,忘记结束符命令末尾执行\G一样会显示,纵向显示
go或者\g:同上,但是显示为横向不分列显示
print或\p:显示当前执行命令
quit或\q:退出mysql
delimiter 后跟结束符号 也可写为 \d ; # 用来定义语句结束符
\d ; # 表示使用;号作为结束符
status或\s # 查看服务器状态
system或\!:执行shell命令,无需退出mysql登录界面执行
如:\! ls /root # 直接在mysql中显示root目录下内容
warnings或\W:语句执行结束后显示警告信息
nowaring或\w:语句执行结束后不显示警告信息
prompt或\R:修改登录后mysql>的提示符
\#:对于新建的对象,支持补全功能;
rehash:对所有对象支持命令补全

服务器语句
help COMMAND:获取帮助信息
如:mysql>help SELECT # 获取select的使用方式,与man同意

正常登陆后显示为mysql>符号,其他提示符表示:
->:表示未输入完整,继续输入
'>:表示表示在语句中缺少'引号,只有前面输入了后面未输入
">:表示语句缺少"引号的后一半
`>:表示语句中缺少`反引号的后一半
/*>:表示语句中缺少C语言注释的后一半符号
C语言注释标准方法:
/* d
ddfadfa
*/
其他选项:
--compress:语句先压缩再发送和返回,节省带宽
--ssl-*:所有与SSL加密相关内容指定

客户端命令使用技巧:
客户端命令支持补全
开启此功能,每次执行要在内存中遍历每个表,影响性能尽量禁用
登录mysql时使用-A选项禁用补全功能
--no-auto-rehash
--disable-auto-rehash
\#:对于新建的对象,支持补全功能;
rehash:对所有对象支持命令补全

mysql输出格式:
mysql --html
登陆后在mysql>SELECT User,Host FROM user;执行完毕显示为html格式的返回语言,复制出来再浏览器执行就可以看到页面展示的风格
mysql --xml
同上的使用方式,支持xml方式输出

其他命令工具:
mysqladmin:管理命令
格式:mysqladmin [options] command [arg] [command [arg]] ...
如:mysqladmin -uroot -p password 'new_pass'
选项:
create DATABASE # 直接创建库
drop DATABASE # 删除库
ping # 测试mysql服务器在不在线,反馈为mysqld is alive说明在线
processlist # 进程列表,列出服务器所有正在执行的线程列表
status # mysql服务器状态
--sleep N # 加此参数会睡眠几秒钟再次显示
--count N # 显示多少次状态
extended-status # 显示状态变量,统计状态数据
variables # 显示服务器变量
flush-privileges # 让mysqld重读授权表
flush-tables # 关闭所有已打开的表
flush-threads # 重置线程缓存
flush-status # 重置大多数的服务器状态变量,计数器置零
flush-logs # 日志滚动和中继日志滚动
flush-hosts # 清除主机内部信息,如:DNS解析缓存,多次连接错误导致的用户连接错误
kill # 终止线程
reload # 等同于flush-privileges
refesh # 等同于flush-logs和flush-hosts同时执行
shutdown # 关闭mysql服务器
version # mysql服务器版本号和当前状态信息
start-slave # 启动从服务器进程复制功能
SQL thread
IO thread
stop-slave # 停止从服务器进程复制功能

mysqldump:备份工具
mysqlimport:导入工具
mysqlcheck:检查数据库完整性工具


MySQL数据类型及sql模型

开发视角:
数据类型
约束
创建数据库、表、索引、视图
SELECT语句

存储引擎:也被成为表类型;
MyISAM:无事务,表锁
.frm:表结构定义文件
.MYD:表数据
.MYI:表索引
InnoDB:事务,行锁
默认配置,所有表共享一个表空间文件:
建议:每表一个独立的表空间文件,默认不打开此特性
.frm:表结构
.ibd:表空间(表数据和表索引),创建之初有初始数据

MySQL查看某个表示什么表类型:
mysql>SHOW TABLE STATUS LIKE 'user'; 查看user表的状态信息,Engine项为表类型

程序语言连接数据库的方式:
动态SQL:通过函数或方法与数据库服务建立连接
嵌入式SQL:与动态SQL类似,但其语句必须在程序编译时完全你确定下来;并由预处理器完成处理;

客户端组件:mysql、mysqladmi、mysqldump、mysqlimport、mysqlcheck
服务器端:mysqld、mysqld_safe、mysqld_multi

/usr/local/mysql/bin目录下均为mysql服务端的执行工具
mysqlbinlog:查看mysql二进制日志
mysqld_safe:安全线程方式启动mysql
mysqlhotcopy:mysql备份工具

my.cnf配置文件
MySQL读取配置文件在UNIX系统中启动过程:
启动时:/etc/my.cnf
然后:/etc/mysql/my.cnf
然后:$MYSQL_HOME/my.cnf
然后:/path/to/file when defaults-extra-file=/path/to/file is specified :即指定
最后:~/.my.cnf
以最后一次读取的配置为最终生效的结果。按次序第一次读取的反而优先级低

mysqld --help --verbose # 此命令可以查看mysqld的默认可写入配置文件的参数

datadir = /mydata/data # 数据存放目录
hostname.err:错误日志,生成数据目录后创建文件
1、此前服务未关闭
2、数据初始化失败
3、数据目录位置错误
4、数据目录权限问题

DBA:
开发DBA:
数据库设计
SQL语句
存储过程、存储函数、触发器
管理DBA:
安装、升级
备份、恢复
用户、权限管理
监控、性能分析
基准测试

数据类型:
数值型
精确数值
int
decimal
近似数值
float
double
real
字符型
定长
CHAR(N)
BINARY
变长
VARCHAR(N)
VARBINARY
text,blob
ENUM
SET
日期时间型
date,time,datetime,timestamp

域属性,修饰符:定义域限制

数据类型定义:
1、能够表示哪种种类数据
2、限定字符长度和占用存储空间
3、定义变长和定长
4、如何比较及排序
5、是否可以被索引

MySQL数据类型分类:遵循ISO 2003标准数据类型
1、字符型
2、数值型
3、日期时间型

数值类型:
1、精确数值型
NUMERIC(g,f):精确定点数值,总长度精度
DECIMAL(g,f):精确定点数值,总长度精度
TINYINT:微整型 1字节,255byte
SMALLINT:小整型 2字节,2byte,最大65535个字符,64K
MEDIUMINT:中整型 3字节,3byte,最大16777215个字符,16M
INT:整型 4字节,4byte,最大4294967295个字符,4G
BIGINT:大整型 8字节,8byte,最大18446744073709551615个字符,8G
整数可用属性:
AUTO_INCREMENT:自动增长
必须使用一个整数类型
必须无符号整型,UNSIGNED
必须建立为PRIMARY KEY或UNIQUE KEY index
必须不能为空
LAST_INSERT_ID():显示出上一次自动生成的数字序列排序到哪里
2、近似数值型:
FLOAT(g,f):单精度浮点型 4字节
DOUBLE(g,f):双精度浮点型 8字节
REAL:独立类型,有时为FLOAT,有时为DOUBLE,以不同平台区分
BIT:按位存储
3、布尔型:TINYINT(1),显示的数值为1
BOOLEAN:
BOOL:

字符类型:
CHAR(M):定长,不区分大小写,最大255个字符
VARCHAR(M):变长,不区分大小写,1-2个byte,最大65535个字符
BINARY:定长,区分大小写
VARBINARY:变长,区分大小写
TINYBLOB:微型大对象,区分大小写,1byte,最大255个bytes
BLOB:标准大对象,区分大小写,2byte,最大65535个字符,64K
MEDIUMBLOB:中型大对象,区分大小写,3byte,最大16777215个字符,16M
LONGBLOB:长大对象,区分大小写,4byte,最大4294967295个字符,4G
TINYTEXT:微型大对象,不区分大小写,1byte,最大255个字符
TEXT:标准大对象,不区分大小写,2byte,最大65535个字符,64K
MEDIUMTEXT:中型大对象,不区分大小写,3byte,最大16777215个字符,16M
LONGTEXT:长大对象,不区分大小写,4byte,最大4294967295个字符,4G
ENUM:枚举型,必须填写列出的字符串,65535种变化
SET:集合型,必须填写列出的字符串,1-64个字符串,存储的是位图

日期时间型:
DATE:日期,CCYY-MM-DD 3byte
TIME:时间,HH:MM:SS 3byte
DATETIME:日期和时间,CCYY-MM-DD HH:MM:SS 8byte
TIMESTAMP:日期和时间,CCYY-MM-DD 4byte HH:MM:SS,内部转换后显示,从UNIX元年计算秒数得出结果
YEAR:年,CCYY或YY 1byte

字符串限定:
NOT NULL:不允许为空
NULL:允许空
DEFAULT:默认值
BINARY:是否区分大小写,已经弃用
CHARACTER SET:字符集,只有字符使用
msyql>SHOW CHARACTER SET; # 显示mysql服务器支持的所有字符集
COLLATION:排序规则,只有字符使用
msyql>SHOW COLLATION; # 显示各字符集下的排序规则

SQL模型:
ANSI QUOTES:双引号和反引号意义相同引用字段名称和表明,单引号用于标识字符串
IGNORE_SPACE:在内建环境中忽略多余空白字符
STRICT_ALL_TABLES:不设置此项则允许所有非法字符,但会有错误警告信息提示
STRICT_TRANS_TABLES:向支持事务的表中插入数据时是不允许的,并且会返回错误
TRADITIONAL:
查询当前模型:
mysql>SHOW GLOBAL VARIABLES LIKE 'sql_mode';

msyql服务器变量:
作用域划分,分为两类:
全局变量:只有root权限才可以修改
SHOW GLOBAL VARIABLES;
对全局生效的变量
会话变量:
SHOW [SESSION] VARIABLES;
只对当前会话生效的变量

生效时间划分,分为两类:
动态调整:可即时修改并生效,临时生效
无需重启服务器,调整后立即生效
静态调整:永久生效
写在配置文件中
通过参数传递给mysqld进程

动态调整参数的生效方式:
全局:对当前会话无效,只对新建立会话有效;
会话:即时生效,但只对当前会话有效

服务器变量:@@变量名
显示:SELECT
SELECT @@global.sql_mode; # @@显示用户变量,一个@显示用户自定义变量
SELECT @@session.sql_mode; # 查看会话变量
设定:SET GLOBAL|SESSION 变量名='value'

MySQL管理表和索引
数据库:
创建数据库:
CREATE {DATABASE|SCHEMA} [IF NOT EXISTS] db_name [create_specification] ...
create_specification:
[DEFAULT] CHARACTER SET [=] charset_name # 指定此库字符集
[DEFAULT] COLLATE [=] collation_name # 指定排序规则
例:CREATE SCHEMA IF NOT EXISTS students CHARACTER SET 'gbk' COLLATE 'gbk_chinese_ci';

cd /mydata/data 目录下会创建一个students的目录,内有db.opt的文件,保存了默认字符集合排序规则
修改数据库:
ALTER {DATABASE|SCHEMA} [db_name] alter_specification ...
ALTER {DATABASE|SCHEMA} [db_name] UPDATE DATA DIRECOTRY NAME
alter_specification:
[DEFAULT] CHARACTER SET [=] charset_name # 指定此库字符集
[DEFAULT] COLLATE [=] collation_name # 指定排序规则
删除数据库:
DROP {DATABASE|SCHEMA} [IF EXISTS] db_name

表:
创建表:
1、直接定义一张空表;
CREATE TABLE [IF NOT EXISTS] tb_name (col_name col_defination,constraint)
col_defination:
data_type [NOT NULL | NULL] | ...
例:CREATE TABLE courses(CID TINYINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,Couse VARCHAR(50) NOT NULL);

创建表同时创建索引:
CREATE TABLE tb1 (id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,Name CHAR(20) NOT NULL,Age TINYINT NOT NULL) ENGINE [*] engine_name
另一种创建索引写法:
CREATE TABLE tb2 (id INT UNSIGNED NOT NULL AUTO_INCREMENT,Name CHAR(20) NOT NULL,Age TINYINT NOT NULL,PRIMARY KEY(id),UNIQUE KEY(name),INDEX(age))
单字段:
PRIMARY KEY
UNIQUE KEY
单或多字段:
PRIMARY KEY (col,...)
UNIQUE KEY (col,...)
INDEX (col,...)
2、从其他表中查询出数据,并以之创建新表;
CREATE TABLE testcourses SELECT * FROM courses WHERE CID <=2;
创建一个新表为testcourses从表courses中查找CID前两行的数据作为新表内容
3、以其他表为模板创建一个空表;
CREATE TABLE test LIKE courses;
desc test; # 查看表结构是否与courses一样

修改表:
ALTER TABLE tb_name;
添加、删除、修改字段
ALTER TABLE student MODIFY CID TINYINT UNSIGNED NOT NULL;
# 在student表中修改CID的字段类型为TINYINT UNSIGNED NOT NULL
ALTER TABLE test CHANGE Couse Course VARCHAR(50) NOT NULL;
# 修改test表中Couse的行名
ALTER TABLE test ADD starttime date default '2013-04-12';
# 添加一行内容starttime类型为date默认值为2013-04-12
添加、删除、修改索引
ALTER TABLE test ADD UNIQUE KEY (Couse);
# 在test表中将Couse字段加唯一键索引
改表名:两种方法改名
ALTER TABLE test RENAME TO testcourses;
RENNAME testcour TO test;
修改表属性:
ALTER TABLE courses ENGINE=InnoDB; # 修改表引擎为InnoDB

删除表:
DROP TABLE tb_name;
选项:
CASCADE:允许级联,删除表时将此表相关联的表全部删除
RESTRICT:不允许级联,删除时不删除关联内容
键也称作约束,可用作索引,属于特殊索引(有特殊限定):B+Tree索引

索引:索引是不能被修改的,只能先删除再创建
创建索引:
CREATE INDEX index_name NO tb_name index_type{BTREE|HASH}
例:CREATE INDEX name_on_student ON student (Name(5) DESC) USING BTREE;
# 创建索引名为name_on_studen的索引在student表中的Name字段中只匹配从左边起的5个字符并以降序排序(ASC表示升序|DESC表示降序),使用BTREE的索引类型
查看索引:
SHOW INDEXES FROM tb_name; 查看表中的索引
删除索引:
DROP INDEX name_on_student ON student;
添加外键索引:
ALTER TABLE student ADD FOREIGN KEY foreign_cid(CID) REFERENCES courses (CID);
# 在表student中将foreign_cid设置为表courses(CID)的外键
SHOW INDEXES FROM student;
# 查看student表的索引是否包含foreign_cid
DELETE FROM courses WHERE CID=3;
# 此时删除courses表中的CID行中的3是无法删除的,因为与student表有关联

外键:
InnoDB支持外键
外键约束不建议使用,会消耗服务器资源

单表查询、多表查询和子查询
DML:
SELECT
INSERT INTO
DELETE
UPDATE

SELECT:查询操作语句
SELECT select-list FROM tb WHERE qualification

查询语句类型:
单表查询:
多表查询:
子查询:

查询所有内容:
SELECT * FROM tb_name;
投影:
SELECT field1,field2 FROM tb_name;
选择:
SELECT * FROM tb_name WHERE qualification;
SELECT * FROM students WHERE Age>=20;
去重,相同的行只显示一次
SELECT DISTINCT Gender FROM students; # 性别选项都有的内容显示出来并去重

FROM子句:要查询的关系 表、多个表、其他SELECT语句
WHERE子句:布尔关系表达式,数值比较无需加符号,字符必须加单引号
=、>、>=、<、<=、<>和!=均为不等于、<=>表示空值也比较的相等符号
+、-、*、%、
逻辑关系(与或非):
AND:SELECT Name.Age,Gender FROM student WHERE Age>20 AND Gender='M';
OR:SELECT Name.Age,Gender FROM student WHERE Age>20 OR Gender='M';
NOT:SELECT Name.Age,Gender FROM student WHERE NOT Age>20;
SELECT Name.Age,Gender FROM student WHERE NOT Age>20 AND NOT Gender='M';
SELECT Name.Age,Gender FROM student WHERE NOT (Age>20 OR Gender='M');
查询区间:查询年龄在20至25之间的人员
SELECT Name.Age,Gender FROM student WHERE Age>=20 AND Age<=25;
SELECT Name.Age,Gender FROM student WHERE Age BETWEEN 20 AND 25;

特殊查询:
BETWEEN ... AND ...
区间查询匹配
LIKE ''
%:任意长度任意字符
_:任意单个字符
REGEXP 或 RLIKE:使用正则表达式
例:SELECT Name FROM student WHERE Name RLIKE '^[XY].*$';
查询名字以X或Y开头的学生
IN:离散取值
例:SELECT Name FROM student WHERE Age IN (18,20.25);
查询年龄为18、20、25的同学
IS NULL 和 IS NOT NULL:匹配为空或不空的
例:SELECT Name FROM student WHERE CID2 IS NOT NULL;
找到表中CID2列不为空的

排序:ORADER BY 默认为升序,因此升序可以省略ASC
ORDER BY field_name {ASC|DESC}

AS:字段或表重命名 例如将Name字段取别名Student
SELECT Name AS Student_Name FROM students;
Name字段就会显示为Student_Name

LIMIT子句:LIMIT [offset,]Count 只显示有限的行
SELECT Name AS Student_Name FROM students LIMIT 2;
只显示结果的前两段
SELECT Name AS Student_Name FROM students LIMIT 2,3;
表示略过前两个从第三个开始显示后3个字段

聚合运算:SUM(),MIN(),MAX(),AVG(),COUNT()
SELECT AVG(Age) FROM students;
# 字段Age的平均值
SELECT MAX(Age) FROM students;
# 找到年龄最大的
SELECT MIN(Age) FROM students;
# 找到年龄最小的
SELECT SUM(Age) FROM students;
# 年龄之和
SELECT COUNT(Age) FROM students;
# 查看有年龄的人共多少个

GROUP BY:分组
SELECT Age,Gender FROM students GROUP BY Gender;
# 按照Gender分组显示
SELECT AVG(Age) FROM students GROUP BY Gender;
# 求男女的平均年龄并排升序
SELECT COUNT(CID1) AS Persons,CID1 FROM students GROUP BY CID1;
# 查询共有多少同学选择了那些课程
组合子句:HAVING qualidication 将group by的结果再次过滤
SELECT COUNT(CID1) AS Persons,CID1 FROM students GROUP BY CID1 HAVING Persons>=2;
# 选出大于或等于2个同学以上的课程

多表查询:例如学生表为students课程表为courses进行组合查询
连接:
交叉连接:笛卡尔乘积
自然连接:两表中某字段值相同的建立连接
SELECT students.Name,courses.Cname FROM students,courses WHERE students.CID1 = courses.CID;
# 表students的CID1列内容与courses表的CID列相同的字段列出
# 以上写法长度太长,可以给表取别名,下面的写法取别名查询
SELECT s.Name,c.Cname FROM students AS s,courses AS c WHERE s.CID1 = c.CID;
外链接:以一张表内容的字段为基准来关联查询
左外连接:... LEFT JOIN ... ON ...
SELECT s.Name,c.Cname FROM students AS s LEFT JION courses AS c ON s.CID1 = c.CID;
# 以students表为准找出Name与课程表courses的Cname进行连接,courses表中不存在的课程显示为空
右外连接:... RIGHT JOIN ... ON ...
SELECT s.Name,c.Cname FROM students AS s RIGHT JION courses AS c ON s.CID1 = c.CID;
# 与上相反,以courses表的Cname为基准,程序有但Name没有的为空
自连接:本表相关联的内容匹配
SELECT c.Name AS student,s.Name AS teacher FROM students AS c,students AS s WHERE c.TID=s.SID;
# 在students表中同一列内容做匹配,以TID和SID匹配老师和学生的关系

子查询:
比较操作中使用子查询:子查询只能返回单个值;
SELECT Name FROM students WHERE Age > (SELECT AVG(Age) FROM students);
# 找出表内同学中大于平均年龄的同学,后面的SELECT为子查询
IN():使用子查询:
SELECT Name FROM students WHERE Age IN (SELECT Age FROM tutors);
# 查找出同学年龄与tutors表老师年龄一样的同学
在FROM中使用子查询:
SELECT Name,Age FROM (SELECT Name,Age FROM students) AS t WHERE t.Age >= 20;
# students表中大于等于20年龄的同学

联合查询:
(SELECT Name,Age FROM students) UNION (SELECT TName,Age FROM tutors);
# 将两个表的相同内容合并

示例:
1、所有不被学习的课程查询
SELECT Cname FROM courses WHERE CID NOT IN (SELECT DISTINCT CID2 FROM students WHERE CID2 IS NOT NULL);
2、挑选出没有教授任何课程的老师
SELECT Tname FROM tutors WHERE TID NOT IN (SELECT DISTINCT TID FROM courses);
3、找出students表中CID1有两个或两个以上同学学习了同一门课程的课表名称
SELECT Cname FROM courses WHERE CID IN (SELECT CID1 FROM students GROUP BY CID1 HAVING COUNT(CID1) >=2);
4、显示每位老师及其所教授课程,没有教授的课程保持为NULL;
SELECT t.Tname,c.Cname FROM tutors AS t LEFT JOIN courses AS c ON t.TID=c.TID;
5、显示每个课程及其相关老师,没有老师教授的课程将其老师显示为空
SELECT t.Tname,c.Cname FROM tutors AS t RIGHT JOIN courses AS c ON t.TID=c.TID;
6、显示每位同学CID1课程的课程名称及其讲授了相关课程的老师名称
SELECT Name,Cname,Tname FROM students,courses,tutors WHERE students.CID1=courses.CID AND courses.TID=tutors.TID;

视图:存储下来的SELECT语句
基于基表的查询结果;

创建视图:
CREATE VIEW view_name AS 查询语句
例:CREATE VIEW sct AS SELECT Tname FROM tutors WHERE TID NOT IN (SELECT DISTINCT TID FROM courses);
# 将SELECT开始后面的查询结果创建为视图名为sct
SHOW TABLES; # 查看表会有一张sct的表
SELECT * FROM sct; # 查看此表为视图查询语句结果
删除视图:
DROP VIEW sct;
物化视图:基表更新物化视图也会更新,消耗资源。mysql不支持物化视图
查看视图对应的SELECT语句:
SHOW CREATE VIEW sct; # 查看sct视图创建的SELECT语句
查看创建表时语句:
SHOW CREATE table courses; # 查看创建表时的语句

mysql命令:
-e:不登录mysql直接执行mysql内部命令,写脚本时常用
例:mysql -e 'CREATE DATABASE edb';
mysql -e 'SHOW DATABASE';

SELECT总结:
选择:SELECT * FOME tb_name WHERE
布尔表达式:
算术运算
比较操作符
其他运算符:IN,BETWEEN ... AND ...,LIKE.RLIKE(REGEXP),IS NULL,IS NOT NULL
逻辑运算:AND,OR,NOT,XOR
DISTINCT

投影:SELECT field1, ... FROM tb_name;
ORDER BY field,... {ASC|DESC}

聚合计算:COUNT(),SUM(),MAX(),MIN(),AVG()

GROUP BY field1,...
HAVING

LIMIT [offset],num

多表查询:
交叉连接:笛卡尔乘积
自然连接:两表中某字段值相同的建立连接
WHERE tb1.field=tb2.field
外连接:
左外
FROM tb1 LEFT JOIN tb2 ON condition
右外
FROM tb1 RIGHT JOIN tb2 ON condition
自然连接

子查询:
FROM
WHERE
比较操作符:子查询只能返回一个字段的单值;
IN:列表(某字段的多个值)

广义查询:包含如下几个操作,因为下面操作都是在查询后才可操作的内容
DML语句:
DELETE
INSERT INTO
UPDATE

INSERT INTO:插入语句
INSERT INTO tb_name(col1,col2,...) VALUES(val1,val2...)[,(val1,val2,...),...]
字符型:单引号
数值型:不需要引号
日期时间型:不需要引号
空值:NULL
例如1:
INSERT INTO tutors SET Tname='Tom',Gender='F',Age=30;
SELECT * FROM tutors ORDER BY TID DESC LIMIT 1;
# 显示tutors表TID最后一行,LIMIT1 是只显示一行的意思,DESC降序排序最后一个显示
SELECT LAST_INSERT_ID();
# 此语句可以查询TID排序到的最后一个数值
例2:
INSERT INTO tutors (Tname,Gender,Age) SELECT Name,Gender,Age FROM students WHERE Age > 20;
# 将后面的SELECT查询结果插入到表tutors中对应的字段里

REPLACE INTO:替换插入


DELETE:删除语句
DELETE FROM tb_name WHERE condition;
例如:
DELETE FROM students; # 清空students表
DESC students; # 查看表结构
INSERT INTO students (Name,Age,Gender) VALUES ('tom',30,'F');
# 插入新的一行
SELECT * FROM students; # 查看表内容,可以看到SID不是重新计数的,是继续跟此前删除表时最后一个ID继续编号
INSERT INTO students (Name,Age,Gender) VALUES ('jerry',30,'F');
# 查看依旧继续排号
TRUNCATE:清空表,并重置AUTOINCREMENT计数器,ID号重写
TRUNCATE tb_name;
例如:
接上面DELETE的例子继续
TRUNCATE students; # 清空表
INSERT INTO students (Name,Age,Gender) VALUES ('tom',30,'F'); # 插入行
SELECT * FROM students; # 查看结果,SID重1开始计数

UPDATE:更新表
UPDATE tb_name SET col1*...,col2*... WHERE

MySQL事务和隔离级别

连接管理器:
接受请求
创建线程
认证用户
建立安全连接

并发控制:
多版本并发控制:MVCC,操作时非元数据而是快照,最后以快照合并方式进行数据整合

锁:
读锁:共享锁
写锁:独占锁或排他锁
LOCK TABLES tb_name {READ|WRITE};
UNLOCK TABLES;
锁粒度:从大到小,MySQL服务器仅支持表级锁,行锁需要存储引擎的支持
表锁:锁定整张表
页锁:锁定数据块,数据页面
行锁:锁定行

例:
lock tables tutors READ; # 将tutors表READ锁
在另一个会话中执行查询;
select * from tutors; # 依旧可以查询
INSERT INTO tutors (Tame,Gender,Age) VALUES ('jerry','M',50); # 提示等待释放锁
unlock tables; # 释放锁
在另一个会话提示执行结束,执行时间为等待直到执行结束的时间

事务:多项操作作为一个处理单元,要么同时完成,要么同时都不完成。
产生大量的CPU和IO操作
RDBMS:ACID
Automicity,原子性,事务所引起的数据库操作,要么都完成,要么都不执行
Consistency,一致性,事务执行完成后,最终结果仍然一直
Isolation,隔离性,保持彼此间互不影响的方式进行并发;
事务调度:事务之间影响最小
MVCC:多版本并发控制
Durability,持久性,事务成功完成,系统必须保证任何故障都不引起事务出现不一致性;
1、事务提交之前就已经写出数据至持久性存储
2、结合事务日志完成;
事务日志:顺序IO
数据文件:随机IO

事务状态:
活动的:active
部分提交的:最后一条语句执行后
失败的:未执行完成的
中止的:不执行
提交的:事务一旦提交无法中止

事务:并发执行
1、提高吞吐量和资源利用率
2、减少等待时间

事务调度:
可恢复调度:
无级联调度:

MyISAM:不支持
InnoDB:支持

启动事务:一堆SQL语句或者ODBC指令
START TANSACTION:启动
提交事务:
COMMIT:提交
回滚事务:
ROLLBACK:回滚

事务提交才算完成操作
事务日志:日志与数据磁盘分别放置在不同设备,避免无法恢复
重做日志:每次数据库操作先写入日志,整个事务完成再到ibd表空间中执行
redo log
撤销日志:将原始状态保留到日志,以便于出现问题时可以撤销回原始状态
undo log
日志组:写满一个写另一个,轮询写入

隔离性:
隔离级别:级别越高安全性越高,但并发能力越低
1、READ UNCOMMITTED:读未提交
2、READ COMMITTED:读提交
3、REPEATABLE READ:可重读,MySQL中默认使用级别,别的会话提交,本会话不变,本会话提交才可读到新数据
4、SERIALIZABLE:可串行,别的会话提交,本会话不变,本会话提交才可读到新数据,但未提交之前对端会话不允许执行任何操作,对方提交后才可以进行事务修改
查看隔离级别:
SHOW GLOBAL VARIABLES LIKE '%iso%';
tx_isolation选项为REPEATABLE READ

并发控制依赖的技术手段:

时间戳
多版本和快照隔离

服务器变量:动态和静态
全局变量:只有root权限才可以修改
修改后不影响当前会话,只对新建会话有效
会话变量:
仅对当前会话有效,而且立即生效
永久有效:
修改配置文件

动态修改:
SET {SESSION|GLOBAL} VAR_NAME='';
SET tx_isolation='READ UNCOMMITTED'; # 将隔离级别改为读未提交
SELECT @@tx_isolation; # 查看某个特定变量的值,已经改为读未提交了

锁饥饿:
死锁:

启动事务:
START TANSACTION; # 启动事务
select * from tutors; # 查看tutors表
delete from tutors where Tname LIKE 'stu%'; # 删除两行stu开头的内容
ROLLBACK; # 回滚事务
select * from tutors; # 再查看tutors表,stu条目又回来了
COMMIT; # 如果删除后直接提交,回滚也没有用了
select @@autocommit; # 自动提交变量,可以查看是否开启自动提交事务
如果没有明确启动事务:
autocommit:能实现自动提交,每一个操作都直接提交;
建议:明确使用事务,并且关闭自动提交。优化策略
set autocommit=0; # 关闭自动提交

保存点:SAVEPOINT sid
回滚至保存点:ROLLBACK TO sid
例如事务执行100个操作,执行到75时错误,撤销到某个保存点
START TANSACTION; # 启动事务
delete from tutors where TID=18; # 删除一行
SAVEPOINT ab; # 创建一个保存点叫ab
delete from tutors where TID=14; # 再删除一行
SAVEPOINT ac; # 创建一个保存点叫ac
delete from tutors where TID=12; # 再删除一行
SAVEPOINT ad; # 创建一个保存点叫ad
ROLLBACK TO ac; # 恢复到12一级,保存点之前的数据会保留,之后的不会

MySQL用户和权限管理
账号:认证
权限:
授权
这些信息保存在mysql库中的
user表:用户账号,全局权限,非权限字段
db表:数据库级别的权限定义
host表:已废弃不再使用,已整合进user表
tables_priv表:表级别权限
columns_priv表:列级别权限
procs_priv表:存储过程与存储函数相关的权限
proxies_priv表:代理用户权限
mysql服务器进程启动时,通过以上表在内存中生成授权表,之后的访问均通过检查上述表进行授权

用户账号:
用户名@主机
用户名:16字符以内
主机:
主机名:www.magedu.com,mysql
IP:172.16.10.177
网络地址:172.16.0.0/255.255.0.0
通配符:%,_ 例如:172.16.%.% 或 %.magedu.com
--skip-name-resolve:启动时加入参数,提高用户连接时的速率

权限级别:
全局级别:SUPER,REPLICATION CLIENT,REPLICATION SLAVE,SHOW DATABASES
库级别
USE mysql;
SELECT * FROM db\G; # 查看库级别权限表,内有可查询创建库之类的选项
表级别:DELETE,ALTER,TRIGGER,INDEX
列级别:SELECT,INSERT,UPDATE
存储过程和存储函数

临时表:内存表
heap:16MB

触发器:主动数据库创建
INSERT,DELETE,UPDATE
user表插入数据同时在log表内记录数据

创建用户:
1、create user username@host [IDENTIFIED BY 'password'];
# create user可以不执行flush privileges,他会直接出发读取授权表

2、 GRANT ALL PRIVILEGES ON db.* TO username@'%' IDENTIFIED BY 'password';
ALL PRIVILEGES:所有权限
GRANT EXECUTE ON FUNCTION db.abc TO username@'%';
# db.abc 表示db库的abc表或者abc存储过程或存储函数,因此需要指定对象类型
object_type:TABLE(表),FUNCTION(存储函数),PROCEDURE(存储过程)
GRANT UPDATE(Age) ON cacatidb.testtb TO 'cactiuser'@'%';
# 表示授权给cactiuser用户只能针对cacatidb库的testtb表进行Age列更新
需要执行flush privileges
SHOW GRANTS FOR 'username@host' # 查看某用户的授权信息
WITH GRANT OPTION:此参数表示创建用户可以授权给其他用户与之相同的权限
3、INSERT INTO mysql.user; # 插入数据到MySQL库的user表中,需要执行flush privileges

删除用户:DROP USER 'username'@'host'

用户重命名:RENAME USER old_name TO new_name
注意:用户名需要加主机'username'@'host'

取消授权:
REVOKE ... RROM user
例如:收回cactiuser的SELECT权限
REVOKE SELECT ON cactidb.* RROM 'cactiuser'@'%';

mysql管理员账号密码忘记:
如果无数据初始化数据库即可
有有效数据的情况:
service mysqld stop # 先关闭数据库
启动mysql_safe时传递参数
--skip-grant-tables和--skip-networking # 重新登录时加此两项参数,跳过授权表和网络,跳过网络主要是预防此时有他人访问
直接进入后
use mysql
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('123456');
# 重置密码,但是使用跳过授权表的方式无法执行重置
UPDATE user SET PASSWORD=PASSWORD('123456') WHERE User='root';
# 改user表的Password项内容
SELECT User,Host,Password FROM user;
# 查看是否更改了Password内容
重新登录即可

MySQL日志管理
建议:
日志与数据最好不要放置在同目录,避免磁盘损坏造成数据无法找回,和性能冲突

错误日志:默认放在数据存放目录内以主机名开头.err结尾
log_error # error log记录位置
log_warnings # 警告日志位置
服务器启动和关闭过程中的信息
服务器运行过程中的错误信息
事件调度器运行一个事件时产生的信息,event
在从服务器上启动从服务器进程时产生的信息

一般查询日志:
general_log # 默认关闭,改为ON即可开启,会产是大量日志IO
general_log_file # 日志位置再数据目录下的主机名.log文件
log # 5.6已经弃用,打开后将所有sql语句全部记录
log_output {TABLE|FILE|NONE} # 输入格式,可用逗号隔开写两种

慢查询日志:
long_query_time # 指定超过此值则定义为慢查询,默认为10 单位为秒,也可以定义为毫秒
log_slow_queries={YES|NO} # 是否记录慢查询日志
slow_query_log # 开启或关闭慢查询日志功能,默认OFF
slow_query_log_file # 记录慢查询日志的位置名为localhost-slow.log

二进制日志:任何引起数据库变化的日志都会记录下来,DML,DDL,DCL操作,
MySQL复制和即时点恢复重要依据;
mysqlbinlog:查看mysql二进制日志,在数据目录下存放,每次重启mysql服务就会滚动一次
重放每个操作,能够生成一模一样的多个服务器
二进制日志的格式:
基于语句:statement
基于行:row
混合方式:mixed
二进制日志事件:
产生的时间,starttime
相对位置,position
二进制日志文件:
索引文件:mysql-bin.index,文本文件,记录起始文件与最近使用文件
二进制日志文件:mysql-bin.000001
查看当前正在运行的二进制
SHOW MASTER STATUS; # Position记录改变语句内容
SHOW BINLOG EVENTS IN 'msyql-bin.00005'; # 查看binlog信息,pos记录了详细对应Position的变化操作
SHOW BINLOG EVENTS IN 'msyql-bin.00005' FROM 107; # 从pos的107开始显示
查看二进制日志文件详细内容起止时间
mysqlbinlog
--start-datetime:起始时间
--stop-datetime:终止时间
--start-position:起始位置
--stop-position:终止位置
例如:
mysqlbinlog mysql-bin.000005 # 查看二进制日志文件内容,at后面的数字表示起始下面的at表示上一个的终止也表示下一个的起始位置
mysqlbinlog --start-position=107 --stop-position=358 mysql-bin.000005 # 指定起止位置显示
mysqlbinlog --start-datetime='2013-04-26 15:14:39' mysql-bin.000005 # 从起始时间显示,会找到最符合时间点的时间节点开始,不指定截止时间会显示到日志尾部
重定向二进制日志文件:
mysqlbinlog --start-datetime='2013-04-26 15:14:39' mysql-bin.000005 > /root/a.sql
手动滚动日志:针对二进制日志,从服务器滚动中继日志
mysql> FLUSH LOGS;
删除二进制日志文件:
mysql> PURGE BINARY LOGS TO 'mysql-bin.000003';
mysql> SHOW BINARY LOGS; # 查看二进制日志信息,000001和2已经被删除
查看二进制日志文件选项:
SHOW GLOBAL VARIABLES LIKE '%log%';
binlog_format值为MIXED混杂模式
log_bin # 是否记录二进制日志,默认为ON,还可以指定位置
sql_log_bin # 控制二进制日志是否记录至日志文件,与上同启用,mysql数据库备份导入时需临时关闭此项,导入后再开启
sql_log_off # 是否记录一般查询文件到查询日志文件
binlog_cache_size # 二进制日志文件缓存大小
max_binlog_cache_size # 二进制日志文件缓存最大上限
binlog_stmt_cache_size # 二进制日志语句相关的缓存大小,与事务相关的日志
max_binlog_stmt_cache_size # 最大的语句相关缓存上限
sync_binlog=# # 多久同步一次二进制日志到磁盘,0位不同步,数字表示对二进制日志每多少次写操作之后同步一次
sync:每次操作日志都从内存同步到磁盘
async:先写入内存,一定时间内的操作一并同步至磁盘
expire_logs_days # 日志存放周期,自动清理二进制日志,默认关闭

中继日志:从主服务器的二进制日志文件中复制而来的事件,并保持为的日志文件;
复制主节点二进制日志,然后再从服务器中执行同样的SQL和IO操作的日志

事务日志:主要维护数据库事务本身的可靠性,ACID,将随机IO转换为顺序IO;
事务性存储引擎用于保证原子性,一致性,隔离性和持久性;
事务日志针对的是数据,将旧数据更新为新数据,回撤时再恢复为旧数据即可
查看事务日志文件选项:
SHOW GLOBAL VARIABLES LIKE '%log%';
innodb_flush_log_at_trx_commit # 将内存中的事务日志同步至日志文件,日志文件同步至数据文件的过程由mysql后台完成。取值:0表示每秒同步,并执行磁盘flush操作;1表示每事务同步,并执行磁盘flush操作;2表示每事务同步,但不执行磁盘flush,性能优;
注:mysql一次写操作先写入到用户空间的缓存中,再被传递到内核空间的缓存中,最后被写入磁盘,这样双缓存的机制可能会导致数据丢失,用户空间已经完成了但其实还未从内核空间转存至磁盘,一旦down机很可能会数据丢失,因此上面提到的0选项就略过内核空间直接写磁盘操作。
innodb_log_buffer_size # 内存缓存大小
innodb_log_file_size # 日志文件大小,默认5M
innodb_log_files_in_group # 定义事务日志文件组由几个文件组成,默认2个,两个文件交替写入
innodb_log_group_home_dir # 日志组文件存放位置,./指当前目录为数据目录
innodb_mirrored_log_groups # 镜像事务日志文件组,允许1组镜像


查看日志相关参数:
SHOW GLOBAL VARIABLES LIKE '%log%'; # 查看跟log相关的服务器变量

FIO:fusion-IO
IOPS:
普通pc:100
scsi:200
SSD:500-2000

数据库存储引擎:
SHOW ENGINES; # 查看mysql支持的存储引擎

MyISAM:
不支持事务,性能优
只支持表锁,导致并发能力差
不支持外键
B树索引、FULLTEXT索引、空间索引
支持表压缩
.frm:表结构文件
.MYD:表数据文件
.MYI:表索引文件
InnoDB:OLTP,大量写操作的业务
事务
行级锁,并行写入执行快
B树索引、聚簇索引、自适应hash索引
表空间,raw磁盘设备
.frm:表结构文件
.ibd:表空间文件
MRG_MyISAM:
将两个MyISAM合并为一个表使用
CSV:
利用文本文件的格式存储表,量数据库之间移至时使用
ARCHIVE:
实现归档
MEMORY:
内存存储引擎,性能极高,数据安全性差
BLACKHOLE:黑洞存储引擎
还有很多第三方存储引擎

存储引擎也称之为表类型:不建议混合使用存储引擎,保持一致性

MySQL备份和还原
备份:副本
RAID1,RAID10:保证硬件损坏而不会业务终止;逻辑不会有任何保障。

备份类型:
热备份:读、写不受影响
温备份:仅可读操作
冷备份:离线备份,读写操作均终止
物理和逻辑备份:
物理备份:复制数据文件
逻辑备份:将数据导出至文本文件中

完全备份、增量备份和差异备份:
完全备份:备份全部数据
增量备份:仅备份上次完全备份或增量备份以后变化的数据
差异备份:仅备份上次完全备份以来变化的数据

备份内容:
数据、配置文件、二进制日志、事务日志、

离线备份:通过主从架构方式停库做备份。
数据安全有保障

热备份:
MyISAM:
借助于LVM快照进行热备
温备份,锁表备份
InnoDB:
xtrabackup
mysqldump:性能差一些

物理备份:速度快,可移植性差
逻辑备份:速度慢,丢失浮点数精度;方便使用文本处理工具直接对其处理,可移植性强

备份策略:主要看业务量和可忍受的还原时长
完全+增量:还原较慢
一周一次完全,每天一次增量
每天一次完全,每小时一次增量
完全+差异:还原快
一周一次完全,每天一次差异
每天一次完全,每小时一次差异

MySQL备份工具:
mysqldump:逻辑备份工具,MyISAM(温)、InnoDB(热)
msyqldump(完全备份)+二进制日志=完全+增量或差异

mysqlhotcopy:物理备份工具,冷备工具

文件系统工具:
cp、scp:冷备份
lvm:逻辑卷的快照功能,几乎热备;
mysql>FLUSH TABLES;
mysql>LOCK TABLES;
创建快照;释放锁,而后复制数据
MyISAM:可直接备份
InnoDB:缓冲区内容同步至磁盘才可以开始备份

三方备份工具:
ibbackup:每台服务器授权5000美元
xtrabackup:开源工具
Amanda和Bacula:网络备份工具,有for MySQL的版本

mysqldump:
db_name [tb1] [tb2]:备份某个库或某张表,此备份可能会丢失数据,所以需先FLUSH TABLES WITH READ LOCK; 先清表再以只读方式锁表,再备份,完成后执行UNLOCK TABLES;
例如:mysqldump -uroot -p jiaowu > /root/jiaowu.sql
还原时需先创建数据库CREATE DATABASE studb;
mysql studb < jiaowu.sql
--all-database:备份所有库
--master-data={0|1|2}
0:不记录二进制日志文件及事件位置
1:以CHANGE MASTER TO的方式记录位置,可用于恢复后直接启动从服务器;
2:以CHANGE MASTER TO的方式记录位置,但默认为被注释掉
--lock-all-tables:备份前锁定所有表,MyISAM数据库必须加此选项
--lock-tables:锁定一张表之后备份
--flush-logs:备份之前锁表后,自动执行日志滚动
--events:备份事件的
--routines:备份存储过程和存储函数
--triggers:备份触发器

如果指定库中的表类型均为InnoDB的,可使用
--single-transaction # 启动热备,热备无需锁表等操作

备份多个库:
--all-databases:备份所有库
--databases DB_NAME,DB_NAME,... :备份指定库
还原时无需创建库
例如:
mysqldump -uroot -p --lock-all-tables -flush-logs -all-databases --master-data=2 > /root/all.sql

备份策略:每周完全+每日增量实现即时点还原
完全备份:mysqldump
增量备份:备份二进制日志文件(flush logs)

完全备份:
mysqldump -uroot -p --lock-all-tables -flush-logs -all-databases --master-data=2 > /root/alldatabases.sql
连接mysql操作:最好先复制二进制文件再删除
mysql>PURGE BINARY LOGS TO 'mysql-bin.000011';
mysql>SHOW BINARY LOGS;
mysql>use tudb;
mysql>DELETE FROM tutors WHERE Age>80;
mysql>FLUSH LOGS;
\q
退出mysql

cd /mydata/data # 进入数据目录
cp mysql-bin.00011 /root/ # 备份二进制日志文件
mysqlbinlog mysql-bin.000011 > /root/mon-incremental.sql # 同样是备份二进制日志文件,推荐使用此方式

模拟周二插入新数据
mysql>use studb;
mysql>INSERT INTO tutors (Tname) Values ('stu123');
mysql>\q
退出mysql

模拟故障
cd /mydata/data
cp mysql-bin.000012 /root
rm -rf ./* # 模拟误删除mysql库数据目录

恢复MySQL库:
cd /usr/local/mysql
scripts/mysql_install_db --user=mysql --datadir=/mydata/data # 初始化库
service mysqld start
mysql -uroot -p < alldatabases.sql # 还原完全备份
mysql -uroot -p < mon-incremental.sql # 还原周一执行的操作
mysqlbinlog mysql-bin.000012 > temp.sql # 将周二的二进制日志转换为sql文本文件
mysql -uroot -p < temp.sql # 还原周二执行的操作
还原到了故障的时刻

使用LVM快照进行数据库备份

二进制日志:
format:
statment
row
mixed

mysqldump:还原时最好关闭二进制日志记录,还原结束后再开启,因为还原时执行的内容无需记录在二进制日志中,并且还会产生大量IO影响还原性能
mysql> SHOW MASTER STATUS; # 查看当前二进制日志状态
mysql>SHOW BINLOG EVENTS IN 'mysql-bin.000001'; # 查看二进制日志详细事件
mysql>SET sql_log_bin=0; # 临时关闭二进制日志
mysql>./ /root/jiaowu.sql # 在mysql内部还原教务数据库
mysql>SET sql_log_bin=1; # 开启二进制日志

逻辑备份缺点:
1、浮点数据丢失精度;
2、备份出的数据更占用存储空间;压缩后可大大节省空间;
3、速度他们,消耗资源,不适合对大数据库做完全备份;

对InnoDB:建议使用热备
--lock-all-tables 或 mysql>FLUSH TABLES WITH READ LOCK;
# 针对事务过程锁过程要等待很久;即便锁定,事务日志还可能在执行写操作,还要等待事务日志同步到磁盘之后才能完成锁定状态
SHOW ENGINE INNODB STATUS; # 查看事务日志执行操作状态,缓冲区无操作后锁定
MVCC:多版本并发控制 REPEATABLE-READ
--single-transaction

使用SELECT INTO OUTFILE备份:只适用于但张表内的数据备份
备份:SELECT * INTO OUTFILE '/tmp/t1.txt' FROM t1 [WHERE clause];
还原:LOAD DATA INFILE '/tmp/t1.txt' INTO TABLE t1; # 需要提前创建表和表格式
# 此备份还原过程不会被记录到二进制日志中,因为非DML语句,但会将备份数据以二进制格式记录在二进制日志中
根据上述备份,使用二进制日志恢复:
use jiaowu;
CREATE TABLE tutors LIKE tutor; # 创建新的tutors表与tutor一致
TRUNCATE TABLE tutor; # 清空tutor表数据
SELECT * FROM tutor; # 查看tutor表内容为空
SELECT * FROM tutors; # 查看tutors表内容也为空
set sql_log_bin=0; # 关闭二进制日志记录
SOURCE /root/a.sql; # 导入a.sql数据

执行裸备份:

几乎热备:LVM
前提:
1、数据文件要在逻辑卷上;
2、此逻辑卷所在卷组必须有足够空间使用快照卷;容纳所有变化的数据;
3、数据文件与事务日志必须在同一逻辑卷,因为如果不在同一逻辑卷就需要分开做快照,此时事务日志与数据文件的一致性就会被破坏;

执行步骤:
mysql>FLUSH TABLES WITH READ LOCK; # 锁定表,快照卷之前要锁表
mysql>FLUSH LOGS; # 日志回滚
mysql>SHOW MASTER STATUS; # 当前二进制日志事件位置Position保存下来
# msyql -e 'SHOW MASTER STATUS\G' > /backup/master-`date +%F`.info # 备份日志位置命令
# lvcreate -L 50M -s -p r -n mydata-snap /dev/myvg/mydata # 为/dev/myvg/mydata卷做快照,大小为50M,只读方式,快照名为mydata-snap
# lvs # 查看lv信息,会有一个mydata-snap的快照卷
mysql>UNLOCK TABLES; # 解锁
mysql>commit # 提交事务,二进制日志会有变化
# mount /dev/myvg/mydata-snap /mnt -o ro # 挂载快照卷至mnt目录
# cd mnt/data # 进入快照卷
# mkdir /backup/full-backup-`date +%F` # 创建完全恢复的目录
# cp -a ./* /backup/full-backup-2013-05-03 # 将快照文件备份到恢复目录
# umount /mnt
# lvremove --force /dev/myvg/mydata-snap # 删除快照卷
# cd /backup/full-backup-2013-05-03/ # 切换到恢复目录
# rm mysql-bin.* -f # 删除二进制日志
# cat /backup/master-2013-05-03.info # 查看二进制日志文件备份节点
# mysqlbinlog --start-datetime='2013-05-03 20:18:34' mysql-bin.000003 mysql-bin.000004 > /backup/incremental-`date +%F-%H-%M-%S`.sql # 将二进制日志备份出来,如果备份时间点后出现多个mysql-bin的日志,那就使用时间做起始,后面跟需要备份的mysql-bin日志文件一并导出到一个sql文件
# service mysqld stop # 停止mysql服务
# rm -rf ./* # 在mysql数据目录下吧所有数据文件全部删除
# cp -a /backup/full-backup-2013-05-03/* /mydata/data/ # 恢复备份
# ls /mydata/data -l # 查看属组属主是否为mysql
# service msyqld start # 启动mysql数据库
mysql>set sql_log_bin=0; # 关闭二进制日志记录
mysql>source /backup/incremental-2013-05-03-20-32-57.sql # 把备份的二进制日志还原
mysql>select * from tutors; # 查看数据是否存在
mysql>set sql_log_bin=1; # 开启二进制日志记录
还原至故障点数据
步骤:
1、打开会话,施加读锁,锁定所有表;
mysql>FLUSH TABLES WITH READ LOCK;
mysql>FLUSH LOGS;
2、通过另一个终端,保存二进制日志文件及相关位置信息;
msyql -e 'SHOW MASTER STATUS\G' > /backup/master-`date +%F`.info
3、创建快照卷
# lvcreate -L 50M -s -p r -n mydata-snap /dev/myvg/mydata
4、释放锁
mysql>UNLOCK TABLES;
5、挂载快照卷,备份
# mount /dev/myvg/mydata-snap /mnt -o ro
# cp -a ./* /backup/full-backup-2013-05-03
6、删除快照卷
# lvremove --force /dev/myvg/mydata-snap
7、增量备份二进制日志:
# mysqlbinlog --start-datetime='2013-05-03 20:18:34' mysql-bin.000003 mysql-bin.000004 > /backup/incremental-`date +%F-%H-%M-%S`.sql

使用xtrabackup进行数据库备份

二进制日志相关的几个选项:
innodb_suppot_xa={TRUE|FLASE}
存储引擎事务在存储引擎内部被赋予了ACID属性,分布式(XA)事务是一种高层次的事务,他利用“准备”然后“提交”(preparp-then-commit)两段式的方式将ACID属性扩展到存储引擎外部,甚至是数据库外部。
sync_binlog=# # 设定多久同步一次二进制日志文件,0表示不同步,建议此项设定为1,保证安全方式写入

percona:商业版
ibbackup:InnoDB online physical backup,$5000每服务器
full
incremental
MyISAM:warm backup,full

LVM --> mylvmbackup(perl scripts)
互联网开源工具,自动化对逻辑卷上的数据文件以快照方式做备份,依旧是几乎热备

percona:开源版
xtrabackup:开源工具
xtradb:xtra专用存储引擎,也是innodb的增强版
可将xtradb下载源码,放置在数据中目录中,替换原有的innodb存储引擎
innodb:

官方:www.percona.com

安装工具:
rpm -ivh percona-xtrabackup-2.0.0-417.rhel5.i386.rpm
rpm -ql percona-xtrabackup

xtrabackup完全备份:

innobackupex

# innobackupex --user=DBUSER --password=DBUSERPASS /path/to/BACKUP-DIR/

如果要使用一个最小权限的用户进行备份,则可基于如下命令创建此类用户:
mysql>CREATE USER 'bkpuser'@'localhost' IDENTIFIED BY 'password';
mysql>REVOKE ALL PRIVILEGES,GRANT OPTION FROM 'bkpuser';
mysql>GRANT RELOAD,LOCK TABLES,REPLICATION CLIENT ON *.* TO 'bkpuser'@'localhost';
mysql>FLUSH PRIVILEGES;

使用innobackupex备份时,其会调用xtrabackup备份所有的InnoDB表,复制所有关于表结构定义的相关文件(.frm),以及MyISAM、MERGE、CSV和ARCHIVE表的相关文件,同时还会备份触发器和数据库配置信息的相关的文件,这些文件会被保存至一个以时间命令的目录中。

在备份的同事,innobackupex还会在备份目录中创建如下文件:
(1)xtrabackup_checkpoints -- 备份类型(如完全或增量)、备份状态(如是否已经为perpared状态)和LSN(日志序列号)范围信息
# 每个InnoDB页(通常为16K大小)都会包含一个日志序列号,即LSN,LSN是整个数据库系统的系统版本号,每个页面相关的LSN能够表明此页面最近是如何发生改变的。
(2)xtrabackup_binlog_info -- mysql服务器当前正在使用的二进制日志文件及至备份这一刻位置的二进制日志事件的位置。
(3)xtrabackup_binlog_pos_innodb -- 二进制日志文件及用于InnoDB或XtraDB表的二进制日志文件的当前position。
(4)xtrabackup_binary -- 备份中用到的xtrabackup的可执行文件;
(5)backup-my.cnf -- 备份命令用到的配置选项信息:
在使用innobackupex进行备份时,还可以使用--no-timestamp选项来组织命令自动创建一个以时间命令的目录,如此一来,innobackupex命令将会创建一个backup-dir目录来存储备份数据。

2、准备(perpare)一个完全备份
一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件的事务。因此,此时数据文件仍处理不一致状态。“准备”的主要作用正是通过回滚未提交的事务及同步已经提交的事务至数据文件也使得数据文件处于一致性状态。

innobackupex命令的--apply-log选项可用于实现上述功能。如下面的命令:
# innobackupex --apply-log /path/to/BACKUP-DIR
如果执行正确,其最后输出的几行信息通常如下:
xtrabackup:starting shutdown with innodb_fast_shutdown = 1
120407 9:01:36 InnoDB:Starting shutdown
120407 9:01:40 InnoDB:Shutdown completed;log sequence number 92036620
120407 9:01:36 innobackupex:completed OK!

在实现“准备”的过程中,innobackupex通常可以使用--user-memory选项来指定其可以使用的内存大小,默认通常为100M,如果有足够的内存可用,可以多划分一些内存给perpare的过程,以提高其完成速度

3、从一个完全备份中恢复数据
innobackupex命令的--copy-back选项用于执行恢复操作,其通过复制所有数据相关的文件至mysql服务器DATADIR目录中来执行恢复过程。innobackupex通过backup-my.cnf来获取DATADIR目录的相关信息。

# innobackupex --copy-back /path/to/BACKUP-DIR
如果执行正确,其输出信息的最后几行通常如下:
innobackupex:Finished copying back files

120407 09:36:10 innobackupex:completed OK!

请确保如上信息的最后一行出现"innobackupex:completed OK!"

当数据恢复至DATADIR目录以后,还需要确保所有数据文件的属主和属组均为正确的用户,如mysql,否则在启动mysqld之前还需要事先修改数据文件的属主属组如:
# chown -R mysql:mysql /mydata/data

service mysqld start 启动mysql服务查看数据是否已恢复

xtrabackup+二进制日志:实现即时恢复

4、使用innobackupex进行增备份

每个InnoDB的页面都会包含一个LSN信息,每当相关的数据发生改变,相关的页面的LSN就会自动增长,这正是InnoDB表可以进行增量备份的基础,即innobackupex通过备份上次完全备份之后发生改变的页面来实现。

要实现第一次增量备份,可以使用以下命令进行:

# innobackupex --incremental /backup --incremental-basedir=BASEDIR

其中,BASEDIR指的是完全备份所在的目录,此命令执行结束后,innobackupex命令会在/backup目录中创建一个新的以时间命名的目录以存放所有增量备份数据。另外,在执行过增量备份之后再一次进行增量备份时,其--incremental-basedir应该指向上一次的增量备份所在目录

需要注意的是,增量备份仅能应用于InnoDB或XtraDB表,对于MyISAM表而言,执行增量备份时其实进行的是完全备份。

"准备"(perpare)增量备份与整理完全备份有着一些不同,尤其要注意的是:
(1)需要在每个备份(包括完全和各个增量备份)上,将已经提交的事务进行“重放”,“重放”之后,所有的备份数据将会合并到完全备份上。
(2)基于所有的备份将未提交的事务进行“回滚”。

于是,操作变成了:BASE-DRI指向完全备份目录
# innobackupex --apply-log --redo-only BASE-DIR

接着执行:指向上一次增量备份目录
# innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR=1

而后是第二个增量:指向最近一次增量备份目录
# innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR=2

其中BASE-DIR指的是完全备份所在的目录,而INCREMENTAL-DIR=1至的是第一次增量备份的目录,INCREMENTAL-DIR=2指的是第二次增量备份的目录,其他依次类推,即如果有多次增量备份,每一次都要执行如上操作;

恢复依旧是:
# innobackupex --copy-back /path/to/BACKUP-DIR # 指向完全备份目录即可,增量已合并

5、Xtrabackup的“流”及“备份压缩”功能

xtrabackup对备份的数据文件支持“流”功能,即可以将备份的数据通过STDOUT传输给tar程序进行归档,而不是默认的直接保存至某备份目录中。要使用此功能,仅需要使用--stream选项即可。如:

#innobackupex --stream=tar /backup | gzip > /backup/`date +%F_%H-%M-%S`.tar.gz

甚至也可以使用类似如下命令将数据备份至其他服务器:

# innobackupex --stream=tar /backup | ssh user@www.magedu.com "cat - > /backup/`date +%F_%H-%M-%S`.tar"

此外,在执行本地备份时,还可以使用--parallel选项对多个文件进行并行复制。此选项用于指定在复制时启动的线程数目。当然,在实际进行备份时要利用此功能的便利性,也要启用innodb_file_per_table选项或共享的表空间通过innodb_data_file_path选项存储在多个ibdata文件中。对某一数据库的多个文件的复制无法利用到此项功能。其简单实用方法如下:
# innobackupex --parallel /path/to/backup

同时,innobackupex备份的数据文件也可以存储至远程主机,这可以实用--remote-host选项来实现:
# innobackupex --remote-host=root@www.magedu.com /path/IN/REMOTE/HOST/to/backup

6、导入或导出单张表

默认情况下,InnoDB表不能通过直接复制表文件的方式再mysql服务器之间进行移植,即便实用了innodb_file_per_table选项,而使用xtrabackup工具可以实现此种功能,不过,此时需要“导出”表的mysql服务器启用了innodb_file_per_table选项(严格来说:是要“导出”的表在其创建之前,mysql服务器就启用了innodb_file_per_table选项),并且“导入”表的服务器同事启用了innodb_file_per_table和innodb_expand_import选项。

(1)“导出”表
导出表是在备份的perpare阶段进行的,因此,一旦完全备份完成,就可以在perpare过程中通过--export选项将某表导出了:
# innobackupex --apply-log --export /path/to/backup

此命令会为每个innodb表的表空间创建一个以.exp结尾的文件,这些以.exp结尾的文件则可以用于导入至其他服务器。

(2)“导入”表
要在mysql服务器导入来自其他服务器的某innodb表,需要先在当前服务器上创建一个跟原表表结构一致的表,而后才能实现将表导入:
mysql> CREATE TABLE mytable (...) ENGINE=InnoDB;

然后将此表的表空间删除:
mysql>ALTER TABLE mydatabase.mytable DISCARD TABLESPACE;

接下来,将来自于“导出”表的服务器的mytable表的mytable.ibd和mytable.exp文件复制到当前服务器的数据目录,然后使用如下命令将其“导入”:
mysql>ALTER TABLE mydatabase.mytable IMPORT TABLESPACE;

7、使用xtrabackup对数据库进行部分备份

xtrabackup也可以实现部分备份,即只备份某个或某些指定的数据库或某数据库中的某个或某些表。但要使用此功能,必须启用innodb_file_per_table选项,即每张表保存为一个独立的文件。同事,其也不支持--stream选项,即不支持将数据库通过管道传输给其他进程进行处理。

此外,还原部分备份跟还原全部数据的备份也有不同,即你不能通过简单地将perpare的部分备份使用--copy-back选项直接复制回数据目录,而是要通过导入表的方式来实现还原。当然,有些情况下,部分备份也可以直接通过--copy-back进行还原,但这种方式还原而来的数据多数会产生数据不一致的问题,因此,无论如何不推荐使用这种方式。

 

posted @ 2019-09-17 11:06  donray  Views(1087)  Comments(0Edit  收藏  举报