arp协议是网络层的协议,但是具体工作在数据链路层,将ip地址和mac地址对应,我们可以使用arp -a命令查看。TCP三次握手建立了可靠连接,这个问题其实是一个两军问题,其实*在不可靠的通信中,不管进行几次握手都是有风险的,因为永远无法确定最后一次通信到达,这个问题其实是一个无解的问题。*3次被认为是相对可靠了。子网掩码不一定要是255,只要连续的1即可,例如一个B类网络可以将255.255.255.0作为子网掩码,那么该网络的可用主机数就只有254了(0是网络号,255是广播地址)。ftp协议会使用2个端口(20用于传输数据,21用于发送命令)。SMTP-25,POP3-110。

linux网络配置

通过ifconfig命令配置的网络只能临时生效。

网卡信息文件

位于/etc/sysconfig/network-scripts/ifcfg-deviceName.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
DEVICE="eth2"
IPADDR="192.168.1.112"
NETWORK="192.168.1.0"
GATEWAY="192.168.1.1"
BROADCAST="192.168.1.255"
BOOTPROTO="static" # 可以为dhcp
HWADDR="00:0C:29:14:65:DC" # mac地址
IPV6INIT="yes"
NM_CONTROLLED="yes"
ONBOOT="yes" # 启动时开启网络服务
TYPE="Ethernet"
UUID=646b18f4-56d3-47bf-bcd9-78fdf96de301
DNS1=192.168.1.111
DNS2=114.114.114.114
USERCTL=no # 不允许非root用户控制该网卡

Centos7修改网卡为eht0

主机名文件

/etc/sysconfig/network

1
2
NETWORKING=yes # 为no表示不工作
HOSTNAME=localhost.localdomain

DNS配置

/etc/resolv.conf

1
2
nameserver 10.0.80.11
nameserver 10.0.80.12

配置好以上的3个参数后执行service network restart即可。

Centos 6以后的网卡配置文件多了uuid字段,如果局域网内uuid重复就可能导致网络启动失败。解决方案

  1. 删除/etc/sysconfig/network-scripts/ifcfg-deviceName中的HWADDR行;
  2. 删除网卡和MAC地址绑定文件,rm -rf /etc/udev/rules.d/70-persistent-net.rules
  3. reboot。

连接到内网的网卡是不能设置网关的。

设置grep高亮显示.编辑~/.bashrc,加入alias grep='grep --color=auto'即可。

运行tcpdump -i eth0 -nnX port 21,可以对ftp通信进行抓包。非对称加密算法中发送端和接受端都维护者自己的公钥和私钥,发送数据的时候发送端使用接收端的公钥(所以我们可以在首次连接的时候看到提示是否下载远程主机的公钥)进行加密,接收端收到数据后使用自己的私钥进行解密。——发送端想要将数据发送给谁就使用谁的公钥进行加密。

抓取特定主机的特定端口tcpdump -i eth4 -nnX '((tcp) and (port 9001) and ((src host 192.168.1.74) or (dst host 192.168.1.74)))'

1
$ rmp -qf filename # 查看文件属于哪个rpm包

yum源的配置文件位于/etc/yum.repos.d

配置光盘yum源只需要将默认的yum源配置文件改名,然后修改/etc/yum.repos.d/Centos-Media.repo修改为光盘挂载点并让它enabled即可。我们之所以可以使用service xxx restart的方式启动程序是因为这些程序被安装到了/etc/init.d

在使用源码安装软件的时候一般按照约定的格式,即:/usr/local/src保存源码包,软件安装位置为/usr/local,安装源码包使用的./configure实际上是生成makefile,使得以后的make和make install可以执行,如果安装报错可以执行make clean进行清理。SELinux的来头很大,是美国国家安全局,配置位于/etc/selinux/confg

显示公网ip只需要访问ipecho.net.

1
$ curl -s http://ipecho.net/plain

权限管理

如果对文件具有写权限,能够对文件内容进行修改,但是不能删除文件,因为文件是属于上一级目录的,必须对上一级目录具有写权限。对文件来讲最高权限是x,而对目录来讲最高权限是w(目录的权限只有0,5(rx),7(rwx)有意义,剩余的所有权限都没有意义)。创建一个文件或者目录,其初始权限是umask表示的值(4个数字,其中第一个表示特殊权限,后面的表示文件权限的掩码)。文件的执行权限必须手工赋予,所以文件的默认最大权限为666,666(-rw-rw-rw-)减去umask 022(—–w–w-),得到644(-rw-r–r–),目录最大权限为777,减去umask 022得到755。注意不能拿数字直接相减,例如umask为033,创建出来的文件权限一样是644。umask的配置文件位于/etc/profile

ACL权限

由于Linux只有owner,group和other3种权限,所以某些场景下可能会权限不够用,此时可用ACL权限,我们可以使用dumpe2fs -h /dev/sda2命令查看输出中的Default mount options: user_xattr acl可以知道该分区支持ACL权限,如果没有我们可以使用mount -o remount,acl /重新挂载根分区。

1
2
3
4
5
6
7
8
9
$ whoami # root
$ useradd tony
$ groupadd stu
$ mkdir /av
$ chown tony:stu /av
$ chmod 770 /av
$ useradd lw
$ setfacl -m u:lw:rx /av # 给用户添加ACL权限是u,同理给组添加是g执行完这个之后文件权限最后一位变成了加号,表示ACL权限,drwxrwx---+
$ getfacl /av # 查看ACL权限

getfacl命令会返回mask,这个mask表示的是最大有效权限,该mask和我们使用setfacl命令进行与运算可以得到真正的权限。

1
2
3
4
5
$ setfacl -m m:rx /av # -R参数可以设置递归ACL权限
$ getfacl /av
$ setfacl -m u:tony:rx /av
$ setfacl -x u:lw /av # 删除lw的ACL权限
$ setfacl -b /av # 清除目录/av的所有ACL权限

设置ACL权限的时候使用-R参数设置递归,则文件可能会产生“权限溢出”,因为给目录设置了执行权限,递归过去文件就有了执行权限。ACL权限的权限溢出很难控制,所以尽量少用ACL权限。如果给目录设置了默认ACL权限,那么该目录中所有新建的文件都会继承该目录的ACL权限:setfacl -m -d:u:username:rx dirname

sudo权限

把本来只有root用户执行的命令赋予普通用户执行,命令是visudo,实际上编辑的是/etc/sudoers。普通用户可以使用sudo -l查看能执行的命令。

1
2
3
4
5
6
7
8
9
root    ALL=(ALL)       ALL
用户名 被管理的主机地址=(可使用的身份)授权命令(绝对路径)
%wheel ALL=(ALL) ALL
%组名 被管理的主机地址=(可使用的身份)授权命令(绝对路径)
user1 ALL=(ALL) /sbin/shoutdown -r now # 普通用户只能执行这一条命令,如果只写shutdown,那么可以执行shutdown后面跟任意参数
# 给普通用户授予添加用户和设置密码的权限,因为执行passwd的时候身份会切回root,所以使用正则进行了限制,防止root密码被修改!
user1 ALL=/usr/bin/useradd
user1 ALL=/usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd "", !/usr/bin/passwd root
user1 ALL=/bin/vi # sudo vi会切换到root,此命令非常危险

文件特殊权限

setuid,setgid和sticky bit权限非常不安全,系统需要使用它进行一些特定的功能,如果滥用可能导致极其严重的后。

setuid

chmod 4755 filename 或者 chmod u+s 文件名(u+s是suid,g+s是sgid,o+s是sbid)

  • 只有可执行程序才可以设置suid权限。
  • 命令执行者需要对该程序具有执行权限。
  • 命令执行者在执行该程序时获得该程序文件属主的身份(在程序执行过程中灵魂附体为该文件的属主)。
  • 仅在程序执行过程中有效,也就是说用户身份改变只在程序运行过程中生效。

密码保存文件/etc/shadow的权限是000,那么普通用户是如何更改自己密码的呢?答案就在passwd命令中:

1
-rwsr-xr-x. 1 root root 28K 6月  10 2014 /usr/bin/passwd

该文件具有suid权限,任何用户对该文件具有执行权限,所以普通用户使用passwd回车的瞬间获得了/usr/bin/passwd文件所有者(root)的权限。那么问题来了,既然普通用户执行passwd的命令的时候身份已经变成了root,那不就可以修改别人的密码了么?答案是普通用户在执行passwd的时候后面不能跟任何参数。

suid非常危险,最典型的就是给chmod 4755 /bin/vi

1
-rwsr-xr-x. 1 root root 889K 6月  10 2014 /bin/vi # 任何普通用户执行vi身份会变为root

为了严格控制suid权限,我们应该定期扫描系统中的suid权限的文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash

# 搜索系统中所有拥有suid和sgid权限的文件
find / -perm -4000 -o -perm -2000 > /tmp/setuid.check

for i in $(cat /tmp/setuid.check)
do
grep $i /root/suid.list > /dev/null
# 检测上一个命令的返回值,如果不为0,证明上个命令报错
if [ "$?" != "0" ]
then
echo "$i is not in listfile" >> /root/suid_log_$(date +%)
fi
done
rm -rf /tmp/setuid.check

setgid

chmod 2755 filename

  • 只有可执行程序才能设置sgid
  • 命令执行者需要对该程序具有执行权限。
  • 命令执行过程中组身份改变为该文件的属组。

locate命令用于快速搜索文件,实际上搜索的是/var/lib/mlocate/mlocate.db.

1
-rw-r-----. 1 root slocate 716K 12月 11 06:46 /var/lib/mlocate/mlocate.db

普通用户没有该文件的任何权限,但是普通用户是可以通过locate命令进行按名查找的。

1
-rwx--s--x. 1 root slocate 40K 6月  10 2014 /usr/bin/locate

当普通用户执行该命令时组都会切换为slocate组,而slocate组对数据库文件具有读权限。

对文件和目录生效。

sticky bit

仅对目录生效。要求所有普通用户对目录具有7权限。

1
2
3
4
5
$ mkdir -p /home/user1/abc
$ chmod 777 /home/user1/abc
$ chmod o+t /home/user1/abc # 或者chmod 1777
$ l /home/user1/abc
$ drwxrwxrwt. 2 root root 6 12月 11 07:10 abc

任何普通用户都能在/home/user1/abc建立文件,但是只能删除自己创建的文件。

/tmp目录默认拥有sbit权限。任何用户都可以在该目录下新建文件,但只能删除自己创建的文件

1
2
$ ll -d /tmp 
drwxrwxrwt. 7 root root 88 12月 11 06:46 tmp

chattr权限

  • 选项i。如果对文件设置,不能对文件进行删除、改名,也不能添加和修改数据;如果对目录设置,只能修改目录下文件数据,但是不能建立和删除文件。
  • 选项a。对文件设置只能对文件追加数据(>>的方式,vi之类的编辑器被禁用,日志非常适合),不能删除和修改数据;对目录设置,只能在目录中建立和修改文件,不能删除。
1
2
chattr +i abc # 该文件被锁定了,无法更改和删除
lsattr abc

系统资源查看

vmstat命令是CPU、内存、IO的整合。dmesg | grep CPU命令可以查看系统自检信息。查看CPU信息cat /proc/cpuinfo。查看系统架构最简单的方法是使用file命令查看一个系统自带命令file /bin/lslsb_release -a查看centos发行版(yum install lsb)。

1
2
3
$ lsof /sbin/init # 查看某个文件被哪个进程占用
$ lsof -c sshd # 查看sshd进程占用了哪些文件
$ lsof -u root # 查看root用户的进程占用的文件

cache和buffer分别是加速数据读取和写入的,策略分别是LRU和FIFO。

系统日志

系统日志存放目录为/var/log/,包含messages(系统主日志文件),secure(认证、安全),dmesg(启动自检)。

分析nginx日志,得到最多访问网站的ip地址的命令为:cat /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -nr

创建一个目录,并进入到该目录:mkdir test && cd $_

关于TCP数据包到达顺序的问题

以前作者也一直以为数据包先发的不一定先到,直到今天才意识这个问题的缺陷,数据包是不一定先发先到,但是对于TCP有一点特殊,若我们接受的数据包是在应用层,并且应用层用的是TCP的传输协议的话,这个顺序是保证,这个顺序的保证是在传输层保证的,举个例子:

client发生数据A,B给server,使用的TCP传输,client发送毫无疑问是先发送A,然后发送B,但是有些搞网络的同学可能会有这个疑问,A跟B在物理层走的链路不一样,传输速度不一样,B是会比A先到达Server,这个是没有错的,但是这个数据包被接受是在网络层跟传输层,请记住网络跟传输层的作用,网络层是保证同一个包的完整,就是说若你的传输层发出的包过大,在网络层(也就是IP层)会被分包,同时在Sever的网络接受的时候会被组包,有一个完整的包才会交给传输层,若包不完整是会丢弃,同时他也不保证你的包的是否达到,数据包的保证是在传输层做的,就是说若传输层(TCP协议才会,UDP并不保证)没有收到对方的确认包,会有超时重传,每个数据包也是有序列号的,同时,传输层就是根据这个序列号来保证A,B包的顺序,即使B比A先到达了,TCP也会是等A到达之后,先把A提交给应用层,再把B的数据提交给应用层,从而保证了,同一条TCP链接,先发的包先到

注:这个顺序的保证是传输层做的,TCP这个协议保证的,UDP并不保证,网络层接收包的顺序是错乱的。