Linux的网络配置: ifcfg系列和ip家族 :)
现在有一台Linux主机, 并未接入互联网.
如何将其接入呢?
显然,我们要配置以下项目:
- IP/mask
- 路由: 默认网关
- DNS服务器
- 主DNS
- 次DNS
- 第三DNS服务器(only4Linux)
对于配置方式,有两种也就是;
- 静态指定
- ifcfg系列 : ifconfig, route, netstat
- ip系列: object { link, addr, route }, ss, tc
- 配置文件
- 以及一些前端可视化工具 (如: RedHat的Setup)
- 动态分配( DHCP ) – (Dynamic Host Configuration Protocol)
ifcfg系列
配置网络接口
由kernel命名.
命名规则:
- 以太网: eth{0,1,2….} (在CentOS7中得到了重新命名,按照插口或者内核加载PCI时读取到的信息来命名)
- 虚拟拨号设备: ppp{0,1,2,…}(点对点)
ifconfig
ifconfig 直接调用是就显示本机所有的接口, 在后面加上网卡的标识(也就是名字了)就可以对这张NIC进行单独的查看和配置.
直接使用起来就像是这样:
基本上常规的信息都是可以看到的, 比如有:
**inet:**标识IPv4地址
**mtu:**最大传输单元
**netmask:**子网掩码
**broadcast:**广播地址
**inet6:**标识IPv6地址
**ether/HWaddr:**MAC地址
在flags
的后面能看到一些大写单词,这些表明当前这个设备的状态,
使用ifconfig可以很方便的配置对应网卡, 直接在查询的后面跟上网卡的标识加上子命令就行了.
最直接的就是网卡驱动程序的关闭和启用:
1 | [root@WWW ~]$ ifconfig eth0 down |
再比如修改本机IP和子网掩码,像这样:
1 | [root@WWW ~]$ ifconfig eth0 172.16.100.10/16 |
注意,这样设置IP后面跟上的子网掩码的格式是不能改变的, 如果想使用类似255.255.0.0
这样的, 需要单独使用netmask
关键字来指定.
像这样:
1 | [root@WWW ~]$ ifconfig eth0 172.16.100.10 netmask 255.255.0.0 |
注意:修改立即生效, 重启失效
如果你在使用Xshell等远程连接工具, 请不要像我一样蠢, 真的敲了上面的命令..你会直接掉线的!
虽然ifconfig支持许多配置项的修改, 但是大部分的修改我们是用不到的.
其中有个[-]promisc
这个选项是用来开启和关闭混杂模式的.而所谓混杂模式就是指不论目的地址是否指向他, 网卡都会将来自接口的所有数据捕获并交给他的驱动程序, 这种模式的应用比如说:wireshark
.
route
路由管理命令–route
使用route查看当前主机的路由表, 常用的参数就是-n
, 不进行反向解析, 也就是全部显示ip而不是名字.
来看一下这个输出,前几项直接翻译就好了嘛, 来看一下FLAGS
, 这里会看到U
和G
两种, 如果添加主机路由, 会有H
标识(Host
). 像之前的ifconfig
看到的一样, U
表示UP
已启用. G
表示这是网关(Gateway
)
如果要进行路由的添加.使用add
子命令.
添加主机路由时, 由于目标ip直接定位到主机IP, 所以不需要添加子网掩码(其实也是可以写的,但是没有必要), 如果要添加的是一个网段的IP, 那么子网掩码是必须要指定的, 两种方法来指定, 一种是直接在后面接上子网长度, 或者明确表明关键字netmask
加上子网IP.
在最后添加dev
关键字来指定网卡, 数据包发往哪一个硬件
1 | [root@WWW ~]$ route add -host 210.**.151.73 gw 59.**.**.1 dev eth0 |
路由设置时要加入默认路由, 也就是找不到请求IP该发往哪里的救命稻草了.
如果路由表被查了个遍也没有找到, 那么就会最后查找默认路由.
默认路由的设定和一般设定几乎没有不同::
1 | [root@WWW ~]$ route add -net 0.0.0.0/0 gw 59.**.**.1 dev eth0 |
也可以直接简写成:
1 | [root@WWW ~]$ route add default gw 59.**.**.1 dev eth0 |
能够添加自然就可以删除, route删除的语法要比添加容易.
以下:
1 | [root@WWW ~]$ route del -host 192.168.19.2 |
这样,删除主机路由不需要添加子网掩码,直接指定目标即可
但是在删除网络路由的时候:
1 | [root@WWW ~]$ route del -net 192.168.0.0 |
提示错误! 在删除网络路由的时候, 子网掩码是必须要添加的项目.
让我们再试一次:
1 | [root@WWW ~]$ route del -net 192.168.0.0/16 |
没有提示! Unix的哲学就是没有提示就是对的!
route命令的添加和删除就是这样了,下面就进入DNS的配置了.
传统意义上的DNS指定是通过修改配置文件进行的.
这个配置文件就是位于/etc/resolve.conf
在其中直接指定nameserver DNS's IP
即可, 如上文所说, 最多指定三个.
在编辑了该文件后, 可以使用nslookup
,host
或者dig
进行解析测试, 推荐使用 dig
.
dig
的简易使用教程:
从域名到IP的解析称为正向解析, 对应的dig操作为 dig -t A DOMAIN ( 也可以直接dig )
从IP到域名的解析成为反向解析, 对应的dig操作为 dig -x IP ( 有些IP并不能被反向解析 )
netstat
ifcfg
系列的最后一个就是netstat
命令, 显示当前本机的端口占用情况.
这是使用最多的功能之一~, 事实上netstat
不仅可以查看端口, 他也可以查看本机路由表, 显示本机接口(NIC)的统计数据.
有点像上面命令的综合.
用法:
1 | [root@WWW ~]$ netstat -r -n |
在查看TCP端口占用时, 常规上我都会加上-antp
选项.
另外, 在Linux的某些发行版上会有ifup
和ifdown
这两个小脚本, 个人实验结果:
在CentOS7上, 是个普通的bash脚本
在Ubuntu Server 14.04 LTS上是个标准的动态链接64位执行程序.
ip家族
ip这一整套的工具名字叫做iproute
, 可以在你的主机下进行rpm -qf `which ip`
.
整个ip系列命令调用方式有点像Python3的urllib…通过整合了全部模块的ip
, 使用子命令进行调用.
我们也可以先看看iproute
这个包都在我们的系统上装了什么.(以CentOS7为例)
1 | [root@WWW ~]$ rpm -ql iproute |
整个ip命令的风格也是很统一的, 总的来说是这样的:
ip [ OPTIONS ] OBJECT { COMMAND | help }
其中的OBJECT就是 ip 的子命令.
常用的OBJECT就是: { link | addr | route | ...}
就一个一个Object来说吧:
link
link是用来查看和配置网卡设备的, 使用ip link [show]
来查看, 当前网卡驱动的状态.
和上面的ifconfig
类似,
1 | LOOPBACK 表明是本地回环 |
最简单的操作就是网卡的启用和关闭了. 使用ip link
的set
子命令就可以了.
如下:
1 | [root@WWW ~] ip link set dev eth0 down |
再使用ifconfig
或者ip link show
看一下, 就会发现UP的标识已经没有了.
也可以使用该子命令进行网卡功能的开启和关闭.就像上面说过的混杂模式的开启和关闭.
下面我们试着关闭网卡的多播功能:
1 | [root@WWW ~]$ ip link set dev eth0 multicast off |
再开启的话即只要后面的off加上换成on就行了~.
ip-link命令 主要用于网络设备的配置,因此不是太过于常用.
与其说link子命令像ifconfig, 不如说addr子命令更像.因为它不仅显示了当前网卡的简要信息,还有当前的本机IP.
addr
1 | [root@WWW ~]$ ip addr show |
值得一提的是, addr显示出的IP地址是通过DHCP协动态获取的.
使用addr常用的操作是进行IP地址的更换.添加.删除等.
我们直接写上add关键字,在后面跟上IP地址以及设备名就可以了.
1 | [root@WWW ~]$ ip addr add 192.168.42.33/16 dev eth0 |
修改后再show一次,你就会看到eth0网卡多了一个IP地址,这个地址是辅助地址.
也就是说: 是留做备用的.除了这样增加地址, 也可以直接进行修改.
使用replace
关键字来进行Ip地址的更换.
删除IP的操作也很简单, 直接将上面的add
改为del
就行了.
回到上面添加IP的操作. 还记得对于硬盘分区,除了通过UUID, 我们还可以通过为分区添加标签(LABEL).
现在我们也可以给网卡添加LABEL了, 在你add IP
时,可以选择在最后填上label 标签名
.
这样在进行ifconfig
的时候, 你会发现显示出的不再是eth..这样的名字, 而是你取得LABEL,也可以认为这是别名.
在del
中也可以指定别名,但那就是在进行删除目标选定的操作了.
接下来再来看一下作用域.(scope), 这个选项的值在进行show
时候也是可以看见的.默认是global.
也就意味该IP全局有效., 除了global(用于内核, IP属于内核)以外还有site(只用于IPv6), link(仅用于本设备[添加了这个IP的网卡]), host(仅用于本机[服务器]内部).
如果想要清空一张网卡上的所有IP,一个一个del
未免太蠢了, 所以ip-address提供了flush
命令, 直接就可以清空指定设备上的所有IP.
route
ip-route作为路由表管理工具, 支持了极多的路由管理和策略.
然而常规操作依然就是show
.add
.delete
.flush
.
但是在添加路由时,ip-route支持更多功能, 比如:原地址伪装.
1 | [root@WWW ~]$ ip route add 192.168.1.0/24 via 172.16.0.1 dev eth0 src 172.16.0.22 |
最后的的src就是伪装ip了, 建议不要乱写了, 其实乱写程序也会直接报错的.
注意:如果不明确注明子网掩码或者写明default,ip-route会都将其当做主机.
再删除路由时, 最好指明白要删除的路由的dest和netmask, 这样可以避免一些模糊的导致删除错误.
ss
ss是一个网络状况查看工具, 当你的网络繁忙,网络连接情况十分复杂, 或者说连接数非常多的时候, netstat
往往会比较卡.而ss
就是一个取代netstat
的工具. 他的速度基本上是netstat
的10倍左右
ss
命令的大体格式就是:
1 | ss [OPTION] ... [FILTER] |
还是先从选项开始吧:
1 | -t : tcp |
原始套接字和标准套接字. 简单的说就是原始套接字更加底层, 它能够对较低层次的协议直接进行访问, 比如:IP,ICMP等,网络监听技术很大程度上依靠RAW SOCKET.
而原始套接字和标准套接字的区别就是原始套接字可以读取内核尚未处理的数据包, 而标准套接字例如流套接字就只能读取TCP协议的数据, 数据报套接字就只能读取UDP协议的数据.
这些选项几乎和netstat
一模一样.
相较netstat更先进的地方是, ss提供了过滤器, 这样就不需要蠢蠢的再去用管道了.
说到了过滤器, 我们就先看一下tcp的常见状态:
1 | LISTEN 监听 ( 处于服务状态 ) |
基本上ss的过滤器格式为 FILTER := [ state TCP-STATE ] [ EXPRESSION ]
简单的表达式语法就是: ( dport := ssh or sport = :ssh )
特别注明一下:语法要求,两端括号一定要加上空格
这样一条合法的查询语句就是:
1 | [root@WWW ~]$ ss -antpo state established '( dport = :ssh or sport = :ssh )' |
关于state后的参数, ss有一个大坑,那就是没有listen状态, 而是listening.
其实常用的命令参数也就是那些相近的.
以上就是ip家族的常用命令了.
上面是在说使用命令配置Linux的网络,现在我们来看一下使用配置文件进行网络的控制.
由于Linux的版本不同, 所以配置文件的位置也不一样.
来自一年后9.5的更新
说起来虽然说是配置文件有两种, 但是如果网络服务是由NetworkManager进行管理的, 应该配置属性到所谓旧的配置文件中, 新的配置文件似乎不会被读取到并且不会生效. 关于这个我还需要再看看. 不知道是网络配置服务根本就没有读取旧的配置文件还是说是先读取的旧配置文件但是又因为新的配置被洗掉了.
总之, 网络属性配置到旧的配置文件总是没错的. 因为NetworkManager服务会根据这个位置的配置文件来写网络属性.
早期的配置文件位于
/etc/sysconfig/network-scripts/ifcfg-IFACE
< - - IP,MASK,GW,DNS相关配置文件/etc/sysconfig/network-scripts/route-IFACE
< - - 路由相关配置文件.
而在新版的Linux, 修改网络配置, 已经转移向了/etc/network/interfaces
这个文件中, 而DNS服务器的配置可以在/etc/resolve.conf
中进行临时指定(开机重写文件).
先说说旧版的配置文件中常见的或者常用的参数说明一下:
DEVICE: 此配置文件应用到的设备
HWADDR: 对应设备的MAC
地址
BOOTPROTO: 激活此设备的地址配置协议
NM_CONTROLLED: 此网卡是否受NetworkManager
的管理控制.
ONBOOT: 系统引导的时候是否激活此设备
TYPE: 接口类型, 常见的有Ethernet
, Bridge
UUID: 设备的唯一标识
IPADDR: 指明IP地址
NETMASK: 子网掩码
GATEWAY: 默认网关
DNS1: 第一个DNS服务器指向
DNS2: 第二个DNS服务器指向
USERCTL: 普通用户是否可控制此设备
PEERDNS: 如果BOOTPROTO是dhcp
, 是否允许dhcp seerver
分配的DNS服务器指向信息覆盖原来的resolve.conf
.
现在就以新版的配置文件来进行说明.
最简单的配置就是直接把这个文件的static
换成dhcp
即可, 将下面的配置全部删去就好了.
如果配置静态IP,可以参照这个图来配置, 必要的属性就是下面的三项: IP地址
, 网关
, 子网掩码
.
如果要配置DNSSever, 要在/etc/resolve.conf, 这个文件配置的信息会在重启时被重写.
之前说过Linux支持最多可以配置配三台DNSServer, 就这样写就可以了:
使用nameserver
关键字来指定服务器地址.
-来自不知道什么时候之后的一个更新- 对于CentOS系统, 一直使用的就是sysconfig下的配置文件, 而Ubuntu, Debian系的系统梗偏向于使用interfaces这种文件. 所以关于时间的说法是不对的. ( 我好菜啊 )
7.8 更新:
进行主机名的设置, 除了可以通过使用hostname
来进行临时的修改, 更好的方法是使用配置文件进行改变.
这个配置文件就是/etc/sysconfig/network在这里面加入
HOSTNAME`的内容 改变将在下一次的重启生效.
来自一年后9.5的更新:
修改主机名在CentOS7版本上还有一些方法, 使用hostnamectl进行主机名的管理:
1 | [root@VM-node0 ~]# hostnamectl status |
你也可以不加命令参数 同样是查看状态. 我们可以看到当前计算机的主机名是VM-node0
. 有趣的是, 当我们使用之前说的hostname
命令去修改主机名的时候会看到:
1 | [root@VM-node0 ~]# hostname localhost |
多了一个新的记录, 这个叫做瞬态的一个主机名 就像之前说过的, hostname修改的主机名是一个临时的结果 在重启之后会被重置. 重置的结果就是上面的一条记录所展示的静态主机名.
那么怎么使用这个工具进行修改呢?
其实也很简单 这个工具提供的修改命令特别好记:
1 | Commands: |
基本上我们只会使用到前两个了, 直接set-hostname
就可以了.
7.25 的更新:
udev
网卡接口的传统命名都是以eth(Ethernet)开头的, 后面跟上[0,1,2,…]. 这样命名的弊端在于, 当我一个接口上面的网卡坏掉了, 接着我把一个新的网卡换上了, 他的命名依旧是同样的后缀. 而他们的HWADDR是不同的. 所以, CentOS7采用了一种可预测的, 统一的一种接口识别机制. udev从CentOS6就有了, CentOS7仍然沿用了这个.
udev是从用户空间通过系统调用来探测硬件设备, 并进行配置的应用程序. 其中最重要的就是是可预测功能.
在CentOS7上, udev支持多种不同的命名方案:
- Firmware 主板上的, 通过芯片
- 或者是 PCI总线上的拓扑结构
来说说网卡的命名机制, 其一也就是基于systemd, 再者就是通过bios的方式. 我们先来看一下systemd的方式.
sysetmd的命名规则如下:
(a) 如果主板上的固件或者BIOS为主板上的集成的设备提供的索引(就比如说PCI线上的哪个槽)可用, 并且可预测则根据次索引进行命名. e.g: eno1;
(b) 如果固件或者BIOSweiPCI-E扩展槽所提供的索引信息可用, 且可预测, 则根据此索引进行命名, e.g: ens1
(c) 如果硬件接口的物理位置先定下可用, 则根据此信息进行命名, e.g: enp2s0;
(d) 如果用户显式启用, 也可以根据MAC地址进行命名: enx2387a1dc56;
(e) 上述都不可用的时候, 则使用传统命名机制.
上述命名机制中, 尽管我们说这是systemd的命名, 但有的仍然需要biosdevname程序的参与.这就意味我们需要安装这些程序并且启用之.
现在我们来把接口的缩写搞得清楚一点:
1 | en == ethernet |
而名称类型, 有这些:
1 | o<index> -- en | o | 1 -- 这里的index,我们把它叫做设备索引号 |
有了这些, 我们就可以进行网卡设备的命名过程:
第一步 : udev有一个辅助程序. 我们之前说Linux的内核编译和管理的时候, 提到过/sys这么个伪文件系统, 其中的信息就是来源于udev这个机制, udev将内核识别的相关硬件及信息映射出来, 输出到用户空间. 从而能够加载相应地驱动和一些额外的服务. 辅助程序: /lib/udev/rename_device. 这个程序会从/usr/lib/udev/rules.d/60-net.rules来加载, 接着根据这个文件里的指令去查询 /etc/sysconfig/network-scripts/ifcfg-XXXX ( XXXX就是对应的网卡名)这个文件, 在前面的Linux网络配置中, 我们知道这个文件中有一个HWADDR对嘛 接着就会拿着这个网卡地址去进行匹配, 如果匹配到了 就会去读取配置文件中那个叫DEVICE
的参数 于是就会将网命名成和DEVICE保持一致. 也就是说, 它取决于配置文件.
如果第一步没能正常执行的话, 就会将进行第二步, 第二步进行的前提是安装了biosdevname
并且在启动时的内核参数(我们说过grub在启动时是支持参数的, KERNEL后面)加上了biosdevname=1, 也即是 安装了biosdevname, 并且没有禁用它 的话, biosdevname这个程序就会到 /usr/lib/udev/rules.d/71-biosdevname.rules中定义的规则来进行网络接口重命名.
如果说第二步也未能执行, 那么就会进入第三步.
第三步就是根据我们网卡自身所携带的信息来进行命名, 每一个设备都会带上一些属性. 这些都被映射到/sys这个伪文件系统上 这个时候命名的规则文件就是/usr/lib/udev/rules.d/75-net-description. 怎么进行命名呢? 这个即根据网卡加载时一些属性:ID_NET_NAME_ONBOARD, ID_NET_NAME_SLOT, ID_NET_NAME_PATH等等( 一般第一或者第二就足够把问题解决了实在没有的时候才会去找后面的 ), 这些都是变量, 由系统来赋予. 通过检查这些变量是否有值, 于是就会被命名成这些参数的值.
如果第三步仍然失败了..那么就不会进行重命名. 保留之前的eth[0,1,2,..].
如果现在想要保留原来的命名方式怎么做呢? 如果直接修改掉rules文件, udev会尽力进行自动重建( 有可能成功 也有可能失败 ) 但是为了彻底禁用, 我们则需要在内核后添加参数, 由于CentOS7使用的是grub2, 而不是旧的grub legacy, 所以和我们之前说的更改内核参数的方法并不一样. 具体的操作步骤如下:
- 编辑/etc/default/grub文件, 在GRUB_CMDLINE_LINUX这一行添加
net.ifname=0
.- 此时并不会被grub2读取, 所以我们要适应grub2自带的工具来重新生成一下配置文件
- 也就是:
grub2-mkconfig -o /boot/grub2/grub2.cfg
- 最后重启系统就行
这样就可以回归传统的命名方式.
网络属性配置
在先前的Linux网络配置中我们已经说了很多关于网络配置的话题. 但是这次的工具是一个专门用来管理NetworkManager的, 有着自己的一套语法. 主要体现在地址配置上. 现在来看一下: nmcli
这个命令和IP命令很相像. 也有很多自己的OBJECT, 命令组成是:
1 | nmcli [OPTIONS...] {help | general | networking | radio | connection | device | agent | monitor} [COMMAND] [ARGUMENTS...] |
其中比较常用的就是connection和device这两个.
首先是 general 这个是用来显示总体信息的:
1 | [root@WWW ~]$ nmcli g status # g 就是general 可以进行简写 |
不过general 的更多作用是要等到后面进行连接的时候才对显现出来. 我们先来看一下后面的一些OBJECT吧
radio
主要用来进行无线网络的配置, 一般我们也不太会用到呢..所以也先忽略掉.
connection – 类似于 ip 的 addr
用来配置网络连接 因此是很重要的一个. 我们来看看他的子命令.
和ip的addr相像, 使用起来也有近似之处.
1 | [root@WWW ~]$ nmcli connection(c) { show | up | down | add | modify | clone | edit | delete | monitor | reload | load | import | export } |
现在我们把问题聚焦在改变IP地址的应用上 我们使用modify子命令, 过程如下:
1 | [root@WWW ~]$ nmcli connection modify enp0s8 +ipv4.addresses 192.168.56.110/24 |
和其他的IP修改一样, 这个时候都需要进行禁用之后立即启动的操作. 现在就是使用connection的子命令up
和down
的时候.
1 | [root@WWW ~]$ nmcli c d enp0s8 ; nmcli c u enp0s8 |
注意到那个[+]号了么? 其实也可以省略, 如果是要移除的时候就使用减号[-], 这个时候就不可以省略了.
整个修改网络属性的语法格式是这样的:
1 | [root@WWW ~]$ ip connection modify IFACE [+|-] setting.property value |
device – 类似于 ip 的 link
device是用来配置网络接口的, 所以使用的场景多在网卡的连接和断开 另外这个device还可以配置wife~
1 | device {show|status|connect|disconnect|delete} |
使用方法基本上不需要进行说明.