mastering-linux-network-administration
Chapter 1: Setting up Your Environment
Getting started
- 网络管理在linux里面是非常有意思而且非常善变的部分,但是其核心内容却没有变,比
如TCP/IP,改变是是serivce如何被控制,比如现在就是systemd的时代
Distributions to consider
- inux世界里面有上百种distribution,但是本书只讨论最出名的两种:
- Debian-based: 本书使用debian8
- RedHat-based: 本书使用centos7
Physical machines versus virtual machines
- 看似不相关联的两个概念(网络和虚拟机)其实在工作中多有非常重要的作用,比如一个
DNS server一开始可能就是一台VM,当它经受过一段时间的测试和检验以后,会把这台
机器换成真实的机器
- VM的好处不言而喻,它可以设置快照,在你搞砸的时候,直接回退到快照就可以了
Chapter 2: Revisiting Linux Network Basics
Understanding the TCP/IP protocol suite
- 实践当中,最受欢迎的网络协议是TCP/IP,而且不仅仅是PC,如今的手机,电视,甚至是厨
房的智能设备,使用的都是TCP/IP
- TCP是Transmission Control Protocol的缩写,它的主要原理是:
- 把网络传输分成不同的sequence(也叫作packet,或者segment)
- 然后把这些senquence传输到目的地
- 在目的地把分开的这些sequence再拼接好.在目的地拼接好要求我们的tcp要有error
correction,并且在发现错误以后,需要有重传机制(才能保证正确的sequence过来)
- 我们先来看看TCP传输data的actual process.这个过程的第一步就是set up connection,
TCP使用的是三次握手机制:
- 发送方首先发送SYN packet给目的方,表达自己希望开启connection的意愿
- 接收方一旦成功接收到这个SYN,会返回一个packet给发送方,这个packet里面包含SYN/ACK
- 发送方收到SYN/ACK以后,会返回一个ACK,三次握手完成
- connection setup之后,就是传输啦.传输的时候就要考虑到世界不是完美的,很多因素
会限制传输的成功:
- 传输过程中会丢包(packet lost),对方完全接受不到
- 传输过程会损坏(corrupted),对方接收到,但是不是完全正确的packet
- 传输的带宽有限
- 对于上面的三种情况,TCP都有预案:
- 对于丢包,TCP会进行超时重传(后面会介绍)
- 对于损坏,TCP有checksum算法,如果checksum算出来和标记的不一致,那么就会标记
当前的packet损坏,并且丢弃它,相当于一个丢包,通过超时重传来再传一个过来.注意
checksum这种机制不是百分之百的可靠,但是已经达到了绝大多数情况都可靠,而且
使用起来比较经济,所以广为流传
- 对于带宽,TCP的应对是其flow control特性,互联网是一个复杂的相互联系的巨大系
统,两个点之间的网络情况,取决于两者之间最"差"的那一段网络.发送方就算能发送
再多的packet,中间的最"差"的那一环处理不了,只能丢弃.发送方发现自己受到的ACK
的数量,远远小于自己发送的packet,就知道中间环节(或者是接收方)处理不了了,那
么它就会"主动"降低发送频率
- flow control具体实现的方法叫做sliding window:
- 接收方会明确自己的receive window,也就是说自己能最多接受多少的数据
- 发送方会根据这个window来发送,也会在接收方的window满的时候,停止发送,并等待
接收方的"可以重新发送"的信息
- 有趣的是,我们"可以重新发送"这个packet也是可能丢的,一旦丢失,那么发送方就永
远都不发送了么?显然不是,TCP有自己的persist timer,一旦timer超时,就会重新发
送一个packet给对方,而对方接受到并返回的话,会给一个新的receive window来表达
自己的容量
- IP协议是真正的处理packet的,IP会把"有意义"的内容,分成大小一致的packet,把这些
packet"分开"传送到目的地(通过IP address来标识),然后IP会把这些packet重新组合
好. IP是网络层的协议,所以这写"分包","合包"的网络任务都是由它来完成的.作为传
输层的TCP完全不关心网络层的工作
- 除了TCP以外,在网络层种TCP/IP协议还包括了UDP,UDP和TCP有非常的相似的地方:它们
都会把transmission分成不同的packet.
- 但是TCP和UDP不同的地方更显著:UDP只管发送packet,它不管packet发送成功与否,换句
话说,如果packet发送不成功,UDP不会重传
- 第一次听到UDP协议的人有时候会犯嘀咕:为什么如此"不可靠的协议"会存在?其实对于
传输协议来说,并不是越可靠越好,因为有很多时候"可靠(超时重传)"并没有用,比如
实时网络通信软件Skype就不需要"超时重传":因为当时一个数据掉了,
会导致某一方听不清楚一段音频,但是重传没有什么意义,因为对话是
实时的.你没听清楚一两个单词已经是既成事实,不能"重传"导致你后
面的都听不清楚.
Naming the network device
- 当前的时间,一个pc拥有两个或者以上的网卡已经是普遍的现象了,比如一台笔记本,就
至少拥有一个有线网卡,一个无线网卡.
- 一台机器上的不同网卡,是可以独立的拥有各自的IP并且相互独立的工作,实际上你甚
至可以在不同的interface直接制造流量!虽然在大部分的Linux发行版上,这种行为是
被禁止的
- 在每台机器上,每个interface都是可以有一个字符来唯一标示自己(限定某台机器):
- 在debian上面的结果
vagrant@1-101-debian-8:~$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:8d:c0:4d brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe8d:c04d/64 scope link
valid_lft forever preferred_lft forever
- 在centos上面的结果
$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:13:08:95 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global enp0s3
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe13:895/64 scope link
valid_lft forever preferred_lft forever
- 在Debian机器上面,有线网卡叫做eth0,但是在CentOS上面,有线网卡却叫做enp0s3,很
显然在不同的distribution上面,network设备的命名方式是不同的:
- Debian是采取的比较老的命名方式:所有有线网卡以eth开头(无线网卡以wlan开头),
第一块网卡就叫做eth0, 第二块叫做eth1,以此类推.这种老的命名方式会从Debian9
开始被放弃
- Centos采用的是最新的网卡命名方式(systemd自带的),en还是代表有线网卡,p代表
Peripheral(外围设备),s代表Serial(总线).上面例子的enp0s3就是说"插在0号外设
3号总线的有限网卡"
- 之所以Debian和Centos最后都采取systemd自带的这种网卡命名方式,是因为原来的命
名方式存在一个缺点:重启机器之后,网卡可能会交换姓名(可能上次是eth0的这次不是
第一个启动的,所以不能叫做eth0了),而使用网卡所在总线的方式能够保证无论如何enp0s3
重启多少次还是叫enp0s3
Understanding Linux hostname resolution
Understanding the net-tools and iproute2 suites
- 很长一段时间里面,net-tools都是linux下面默认的网络管理工具,其标志性的命令如下:
- net-tools的问题在于,它已经超过10年没有更新过了,所以很多的distribution已经决
定抛弃这个package,转而支持功能一致(但是命令不一致),而且一直更新的iproute2
- 虽然net-tools已经被抛弃,但是由于大量的脚本是使用它们书写的,所以很多时候distribution
还是可以让你通过命令安装net-tools,只不过自己默认的package已经是iproute2了,
比如在centos上面,默认安装了iproute2,但是如果你需要net-tools,也可以通过如下
的命令安装
# yum install net-tools
- iproute2查看网卡信息的方式和ifconfig有所不同,使用的是ip命令
$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq portid b82a72ddc9cb state UP group default qlen 1000
link/ether b8:2a:72:dd:c9:cb brd ff:ff:ff:ff:ff:ff
inet 192.168.0.93/22 brd 192.168.3.255 scope global eno1
valid_lft forever preferred_lft forever
inet6 fe80::ba2a:72ff:fedd:c9cb/64 scope link
valid_lft forever preferred_lft forever
- iproute2里面还有一个比ip名气大的多的命令:hostname,可以让你在shell里面明确当
前你是在哪台机器上面
$ hostname
openstack3
Manually managing network interfaces
- 在大多数情况下,我们的linux机器插入网线就可以上网.这是因为在背后DHCP服务器为
接入网络的host自动分配了IP地址.
- 我们这一节主要学习通过命令行的配置来让机器上网,命令行配置是GUI配置的基础,理
解了命令行配置网络,GUI就非常容易掌握了(因为GUI其实就是替我们运行命令)
- 在进行配置之前,我们首先要看下自己的网络通不通,方法就是使用命令ping:
- 首先需要明确的是配置文件的地址,对于debian来说,网络配置文件的地址位于
/etc/network/interfaces
- 需要注意的是,这个文件并不是必须的.很有可能的是,你打开这个文件,发现里面什么
东西都没有.如果是这样的话,那么说明这台机器的网络是通过Network Manager来配置
的.
- Network Manger是一个GUI版本的配置网络的工具,当你安装了desktop版本的linux的
时候,很有可能Network Manager也被安装上了,并且作为了default的网络配置服务,前
面的/etc/network/interfaces就不再起作用啦(会变成一个只含有loopback网卡设置
的文件)!
- 对于把linux作为桌面开发的情况,Network Manager是更好的选择,而Linux大部分情况
下都是作为server(而且没有GUI)来使用,这种情况下,/etc/network/interfaces是更
好的选择
- 我们现在来看一个interfaces文件的例子
# The loopback network interface
auto lo
iface lo inet loopback
- 拥有上面这个例子的机器,很有可能安装了Network Manager,并且作为自己的默认网络
配置.因为除了loopback以外,没有任何的有线或者无线网卡的配置
- 为了证实我们的判断,我们需要使用ps命令来查看后台有哪些进程在运行,里面是不是
有NetworkManager,如果有,结果会是如下
$ ps aux | grep NetworkManager
446 ? Ssl 0:00 /usr/sbin/NetworkManager --no-daemon
- 好了,我们再来看看,如果没有安装NetworkManager的机器上面interfaces文件是什么
样的
# The loopback network interface
auto lo
iface lo inet loopback
# Wired connection eth0
auto eth0
iface eth0 inet dhcp
- 和上面interfaces文件不同的地方是多了eth0的配置:
- auto lo的意思是,我们希望eth0自动启动
- dhcp的意思是,我们希望这个网卡从dhcp server里面获取自己所有的配置
- 值得注意的是,dhcp现在已经发生了一些进步,衍生出了新的技术:
- 传统的dhcp:每次有新机器加入网络,就分配一个新的ip给这个机器.但是如果这个机
器重装,或者使用livecd启动,那么dhcp不会认得它,会给它一个新的ip地址
- 新的static lease技术:DHCP server会把机器的mac地址和ip进行一一对应,也就是
说,无论你的机器怎样重装,只要你的mac地址不变,dhcp server就保证每次分配给你
的ip地址都是一致的!这是非常重要且有用的特性
- 最后我们来看一个使用static ip的例子
# The loopback network interface
auto lo
iface lo inet loopback
# Wired connection eth0
auto eth0
iface eth0 inet static
address 10.10.10.12
netmask 255.255.248.0
network 10.10.10.0
broadcast 10.10.10.255
gateway 10.10.10.1
- 我们这里的配置文件里面使用static替代了dhcp,这个非常的重要,如果忘记更改还是
使用dhcp的话,后面的address等配置都将不再起作用
- 更改以后,不会立刻起作用的,因为linux网络服务是在启动的时候,已经把这个文件的
内容加载进了内存,所以我们需要重启linux网络服务,让它来重新加载这个配置文件,
鉴于systemd已经是Linux默认的配置,所以我们的重启服务也是通过systemd来的,在
debian上面,网络服务叫做networking.service(也就是说其他distribution网络服务
可能会有不同的名字,比如cetos上面就叫做network.service)
# systemctl restart networking.service
- 上面的操作,在centos上面,会有比较大的不同.
- 首先是配置文件的不同,在centos上面,配置文件的地址变成了多个,这些个配置文件都
统一存放在一个文件夹下面.这个文件夹下面会以ifcfg-xxx的形式来为每个网卡接口
提供一个配置文件.
- 假设我们有两个网卡enp0s3和enp0s8,那么network-scripts文件夹下的内容如下
$ pwd
/etc/sysconfig/network-scripts
$ ls | grep ifcfg
ifcfg-enp0s3
ifcfg-enp0s8
ifcfg-lo
- 我们再来看看其中的一个文件的内容,如果是dhcp的,例子如下
HWADDR="08:00:27:97:FE:8A"
TYPE="Ethernet"
BOOTPROTO="dhcp"
DEFROUTE="yes"
PEERDNS="yes"
PEERROUTES="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_PEERDNS="yes"
IPV6_PEERROUTES="yes"
IPV6_FAILURE_FATAL="no"
NAME="enp0s3"
UUID="a5e581c4-7843-46d3-b8d5-157dfb2e32a2"
ONBOOT="yes"
- 我们要想把其中的dhcp换成static的话,需要改成如下
HWADDR="08:00:27:97:FE:8A"
TYPE="Ethernet"
BOOTPROTO="static"
IPADDR=10.10.10.52
NETMASK=255.255.255.0
NM_CONTROLLED=no
DEFROUTE="yes"
PEERDNS="yes"
PEERROUTES="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_PEERDNS="yes"
IPV6_PEERROUTES="yes"
IPV6_FAILURE_FATAL="no"
NAME="enp0s3"
UUID="a5e581c4-7843-46d3-b8d5-157dfb2e32a2"
ONBOOT="yes"
- 其实详细的更改就是把BOOTPROTO这一行换成了
IPADDR=10.10.10.52
NETMASK=255.255.255.0
NM_CONTROLLED=no
- 前两行配置非常清楚,第三行的意思是:我们不希望使用NM(NetworkManager)
- 配置完之后,我们需要重启网络来让我们的设置起效,在centos上面网络服务叫做
network.service(在ubuntu上面叫做networking.service)
# systemctl restart network.service
Managing connections with Network Manager
Chapter 3: Communicating Between Nodes via SSH
- SSH是Linux上面最重要的工具之一,特别是当前Linux主要作为服务器,而不是桌面版来
使用,这样一来SSH的重要性就更高了
Using OpenSSH
- ssh的最大便利,在于利用相对非常小的网络带宽(比起windows的远程桌面),就可以做到
在异地控制远程的机器
- 远程处理这种事情,SSH并不是第一个这么做的软件,在它之前存在过类似功能的软件:
- ssh能够胜过其他软件,成为远程办公事实上的标准,原因在于其安全性:ssh的connection
都是加密的
- ssh有两个版本的协议protocol1和protocol2,因为protocol1已经不再安全了,所以没有
软件会再使用.当前所有的openssh默认protocol2为其默认协议
- 默认情况下,ssh使用22端口来进行通信.所以如果这个端口被防火墙block的话,你是无
法使用openssh的(windows上面会经常block 22端口)
- 当然你也可以指定ssh跑在不同的端口,比如2222(vagrant经常这么做)
- openssh是一个开源程序软件,其包括如下的几个二进制工具:
- ssh: 就是我们前面一直说的ssh客户端,替代rlogin, telnet
- scp,sftp: 文件从本地到远程之间的传输
- sshd: ssh服务器
- ssh-keygen:生成密钥
- ssh-agent, ssh-add:帮助用户不用每次都输入密钥密码
- ssh-keyscan:扫描一群机器,记录其公钥
Installing and configuring OpenSSH
- OpenSSH分成了两个部分:
- 客户端的ssh: 默认所有发行版都会默认安装,可以远程连接其他机器
- 服务器端的sshd: 默认都不会安装,只有安装了,其他机器才可以连接到你
- debian类型的发行版可以通过如下命令来查看某个软件是否按照(i代表安装了,p代表没安装)
$ aptitude search openssh-server
i openssh-server
p openssh-server:i386
- 安装了以后,确定机器上面的ssh server是否允许,是通过ps命令,看到sshd -D一般就
说明在运行了
$ ps ax | grep sshd
1915 ? Ss 0:00 /usr/sbin/sshd -D
- 如果没有运行,那么就要使用systemctl来进行启动啦
# systemctl start ssh.service
- 多插一句,systemctl是以后发行版的标配,以后发行版就是靠不同的service name来区
分彼此了.比如:
- 在debian上面ssh服务叫做ssh.service,而centos上面叫做sshd.service
- 在debian上面network服务叫做networking.service,而centos上面叫做network.service
- systemctl还有几个很重要的命令:
Connection to network hosts via openssh-client
The OpenSSH config file
- openssh的运行会有一些默认的设置,在linux更改某个软件设置的方法通常是使用设置
文件,ssh的设置文件一般是在$HOME/.ssh
- 一般来说,你使用了ssh-keygen来创建私钥的情况下,默认会有的文件是:
- known_hosts
- id_rsa
- id_rsa.pub
- 一个不会默认生成,需要你自己创建的文件是config,这个文件非常有用,我们来看一个
典型的config文件的内容
# ~/.ssh/config
Host icarus
Hostname 10.10.10.76
Port 22
User jdoe
Host daedalus
Hostname 10.10.10.88
Port 65000
User duser
Host dragon
Hostname 10.10.10.99
Port 22
User jdoe
- 有了这个文件里面的这些配置,我们的机器就能直接使用icarus, deadalus这些主机名
无论是否相应项目存在于DNS里面.
- 可以看到,默认的port和user也可以在这里设置
Understanding and utilizing scp
- 前面说了openssh是一个软件包,ssh是其中的一个主要用途(远程连接控制terminal)
- openssh中另外一个重要的程序就是scp: 把一个文件传送到远程
Transferring files to another node via scp
- 先看第一个例子,把my-image.jpg拷贝到远程的一台机器上,那个机器上一有jdoe的账号
$ scp my-image.jpg 192.168.1.200:/home/jdoe/
- 如果我们在~/.ssh/config或者是/etc/hosts里面设置了hostname,那么可以使用hostname
来替代ip
$ scp my-image.jpg bar:/home/jdoe
- 如果我们每次都拷贝到home目录,那么没必要每次都写/home/jdoe,可以使用如下两种
方法来替代
$ scp my-image.jpg bar:.
$ scp my-image.jpg bar:~
- ssh可能会使用有别于22的端口,这个时候,需要使用-P来指定
$ scp -P 6022 my-image.jpg jdoe@bar:~
- 我们还可以从remote拷贝文件到本地,还可也拷贝文件夹
$ scp -r jdoe@bar:~/myimages .
Tunneling traffic via SSH
Generating public keys
- 除了密码以外,ssh还支持public key authentication,这个比密码要安全的多
- public key的验证方式,最好要单独使用.换句话说,一旦使用public key,就要放弃密
码的登录方式.因为木桶的容积取决于最短的一截,密码登录的安全性太低
- public key登录的方式,可以不用prompt用户输入密码的阶段,非常的方便
- 创建public key的方式是ssh-keygen,需要注意的是,默认生成key的文件夹是~/.ssh,里
面有两个文件:
Keeping SSH connections alive
- 从安全角度考虑,所有的ssh连接都不是一直alive的,如果一段时间内没有数据的传输,
那么ssh connection会自动的断掉
- 从client的角度上来讲,不停断掉的ssh connection肯定体验不友好,那么为了应付ssh
server的要求,我们可以选择从client端每隔一段时间发送一个special的packet来告诉
server,"client端并没有离开,它还是需要连接的"
- 这个特殊packet的设置是通过ServerAliveInterval.我们前面学过~/.ssh/config这个
每个用户适用的setting,在它里面:
- 为某个connection设置的方法是(设置60秒发送一次特殊packet)
Host icarus
ServerAliveInterval 60
Hostname 10.10.10.76
User jdoe
- 为所有的connection设置60秒发送packet
Host *
ServerAliveInterval 60
- 说到配置文件,除了~/.ssh/config这个为某个用户起作用的设置外,还有一个能够影响
所有用户的设置(具体来说就是所有ssh出去流量的设置)
/etc/ssh/ssh_config
- 如果当前的机器作为ssh server,也会有一个为所有ssh进入流量的设置
/etc/ssh/sshd_config
Chapter 4: Setting up a File Server
- 前面说到了openssh软件包里面的scp命令可以在多个server之间传递数据,但是那个只
能是比较小的,少数文件的传输,大文件,数目多的文件,还是需要一个file server来管理
File server considerations
- 在linux上面,有如下三种创建file server的方式:
- NFS(Network File System)
- Samba
- SSHFS(Secure Shell File System)
- 在操作系统的支持方面,三者有所不同:
- NFS:不支持Windows系统(Windows版本的NFS佳作Services for NFS的授权很贵)
- Samba支持所有的主流操作系统(Windows,Linux, MacOSX),但是它也有自己的问题,
那就是对于permission的支持,确切的说是Unix-like系统上面的permission的支持
不够
- SSHFS也支持所有主流操作系统,只不过在windows上面需要安装额外的软件
NFS v3 versus NFS v4
- 对于NFS来说,版本很重要,当前几乎所有的Linux发行版都是使用的NFS4版本
- 当然还是有发行版会使用NFS3,两者的趋避在于NFS4使用了file lock
Setting up an NFS server
- 第一步肯定是安装软件了:
- 第二步是确保daemon服务进程的启动
- 第三步就是更改配置文件:
- 配置文件的位置在
/etc/exports
- 一个可行的配置文件的内容
/exports/docs 10.10.10.0/24(ro,no_subtree_check)
/exports/images 10.10.10.0/24(rw,no_subtree_check)
/exports/downloads 10.10.10.0/24(rw,no_subtree_check)
Creating networked filesystems with SSHFS
Chapter 5: Monitoring System Resources