UP | HOME

mastering-linux-network-administration

Table of Contents

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

  • 对于人来说,使用英文的name比使用数字的ip来的更加的方便.但是在linux上面,要想让 hostname lookup变得有意义,就必须得需要些配置.
  • 你可以先ping一下你的目的机器的hostname,看看有没有回应,如果hostname配置的不 正确,通常会有如下的反应:
    • ping hostname失败
    • ping ip却可以成功
  • 如果和上面两条的反应一致的话,问题就是出在你的"hostname和ip对应"的那一条DNS 信息不存在.
  • 对于机器来说,它是只知道ip这个东西的,你告诉它连接某个hostname,它需要到一个"字 典"里面找某个hostname对应的ip是什么.这个"字典"就叫做DNS (Domain Name System)
  • DNS在不同的系统里面实现的情况不同:
    • 在windows上,一旦一个ip分配给一个host(比如通过DHCP),那么DNS会马上把这个机 器的"hostname+ip"的组合注册好.
    • 在Linux上,虽然上述机制也存在,需要额外的配置,在绝大部分的Linux网络中,上述 机制都不会去开启,也就是说LAN内的机器在默认情况下,是无法通过ping hostname 的方式来找到对方
  • 对于linux host来说,寻找一个hostname的ip,它们第一个想到的不是DNS,而是一个文件, 和DNS这种分布式的存储数据不同,这个文件就locally的存在linux host的文件系统里 面,位置是/etc/hosts.只有在这个文件里面找不到hostname的情况下,DNS server才会 起到作用.
  • 换句话说,/etc/hosts的优先级高于DNS server,在hostname存在于两个地方,但是ip不 同的情况下,/etc/hosts里面的值会起作用(会覆盖DNS server里面的值)
  • 下面就是一个/etc/hosts的例子
    127.0.0.1    localhost
    127.0.1.1    trinity-debian
    # The following lines are desirable for IPv6 capable hosts
    ::1     localhost ip6-localhost ip6-loopback
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters
    
  • 在大多数的hosts文件里面,我们都可以看到localhost,这个localhost是一个hostname 的"保留字",它表示"本机",其ip地址可以是127.0.x.x里面的任意一个,但是基本上都会 使用127.0.0.1
  • 我们还可以看到trinity-debian,这个也指向到了127.0.0.1,那么我们在本机ping trinity-debian,也会得到和ping localhost一样的结果
  • 如果你在内网有个地址经常使用,你可以给它起一个hostname,并且加入到/etc/hosts里面
    10.10.96.10 potato
    
  • 从原理上来讲,我们设置可以把一个外网的ip和hostname(比如网站地址)加入到这里, 但是这属于一种漏洞,有些安全系数很高的网站会屏蔽这种做法
  • /etc/hosts的优先级高于DNS这个默认的设置,也是可以通过配置来改变的,这个优先级 指导配置文件的位置位于/etc/nsswitch.conf.我们可以看到默认情况下寻找hosts的 优先级顺序(这里是file优先,dns最后)
    $ cat /etc/nsswitch.conf | grep hosts
    hosts:          files dns
    

Understanding the net-tools and iproute2 suites

  • 很长一段时间里面,net-tools都是linux下面默认的网络管理工具,其标志性的命令如下:
    • ifconfig
    • route
    • netstat
  • 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:
    • 如果能ping通一个外网地址,那网络肯定是通的,比如
      $ ping -c 2 www.baidu.com
      
    • 否则,如果能ping通local DNS或者DHCP server,那说明至少内网是通的
    • 如果上面两步都失败,那么才需要真正的开始配置网络
  • 首先需要明确的是配置文件的地址,对于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

  • 对于linux来说,如果安装的时候选择了GUI桌面,那么十有八九是会安装NetworkManager 的,我们如何来确认NetworkManager是否安装呢?需要如下的命令
    # ps ax | grep NetworkManager
    
  • 我们还有double check的方法:看package是否安装:
    • 在debian-like上面是
      # aptitude search network-manager
      
    • 在centos上面是
      yum list installed | grep NetworkManager
      
  • 千万不要以为只有GUI才可以使用NetworkManager,其实命令行也可以,使用如下命令
    # nmtui
    

Chapter 3: Communicating Between Nodes via SSH

  • SSH是Linux上面最重要的工具之一,特别是当前Linux主要作为服务器,而不是桌面版来 使用,这样一来SSH的重要性就更高了

Using OpenSSH

  • ssh的最大便利,在于利用相对非常小的网络带宽(比起windows的远程桌面),就可以做到 在异地控制远程的机器
  • 远程处理这种事情,SSH并不是第一个这么做的软件,在它之前存在过类似功能的软件:
    • telnet
    • rlogin
  • 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还有几个很重要的命令:
    • 检查当前ssh server的状态
      # ssh status ssh.service
      
    • 开启启动ssh server服务
      # ssh enable ssh.service
      
    • 开启关闭ssh server服务
      # ssh disable ssh.service
      

Connection to network hosts via openssh-client

  • 使用ssh访问其他的服务器不用做什么准备,因为openssh-client无论在哪个发行版都 是默认安装的
  • 如果你能够解析对方的hostname,那就用hostname,但是大多数情况下是要用ip,格式 是hostname@ip(hostname省略就是和当前用户一致,如果远程没有,就会让你输入)
    $ ssh jdoe@192.168.1.201
    
  • 既然普通用户jdoe可以登录,那么root作为一个用户当然理论上也是可以远程登录的啦 但是从安全性的角度考虑,很多发行版都不会允许以root的身份登录:
    • centos默认不允许root以任何形式进行远程访问
    • debian默认不允许root以"密码"的形式访问,使用RSA就可以
  • ssh binary最主要的一个参数是-p可以在远程机器指定了一个非22的端口的时候进行 设置:比如远程机器设置了6022作为自己开发的ssh端口,那么我们就要
    $ ssh -p 6602 jdoe@chupacabra
    

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

  • ssh tunnel是一个很有意思的东西,因为它把ssh这种"两点之间"的联系扩展到了"三 点":也就是说可以通过"增加额外的一个跳板"来完成"两点之间"的联系
  • 我们来看看ssh tunnel的规则,我们使用使用springboard来表示"额外的跳板host"
    $ ssh -L <local-port>:<hostname-springboard-know>:<hostname-springboard-know-port> <username>@<springboard-ip>
    
  • 这个规则看起来有点难度,我们来看一个实际的例子:
    • 我们现在在公司内网,有一个可以访问到的ip 10.10.10.101上面运行着linux的vnc server
      $ vncviewer localhost:5901
      
    • 因为10.10.10.101的这个VNC服务是建立在localhost的,所以我们通过10.10.10.101 是无法访问的,我们需要建立一个tunnel,把10.10.10.101的port"映射"到我们的port
      ssh -L 5900:localhost:5901 jdoe@10.10.10.101
      
    • 注意,这里的localhost是对于10.10.10.101来说的localhost,换句话说就是"对于 跳板机来说的localhost"
  • 严格的说,上述的例子还是不够完美,因为我们还是只出现了"两个"host,只不过某个 服务在一台host上面是只有localhost访问的,下面的例子是更贴切的tunnel例子:我们 回到家以后,无法直接ping通,那么我们这次真的要借助一个跳板机了:公司的vpn服务 器,公网ip为66.238.170.50:
    • 这次首先在10.10.10.101上面不能再跑localhost的例子了得跑一个bind到如下地 址的服务
      0.0.0.0:3389
      
    • 对于在家里的我们来说,公司vpn服务器公网地址66.238.170.50是可访问的,而对于 66.238.170.50来说,10.10.10.101是可以理解的内网地址,所以我们把家里机器的 3388端口绑定到公司内部机器3389
      $ ssh -L 3388:10.10.10.101:3389 jdoe@66.238.170.50
      
    • 好了,我们只需要在家里访问如下地址就可以了
      localhost:3388
      

Generating public keys

  • 除了密码以外,ssh还支持public key authentication,这个比密码要安全的多
  • public key的验证方式,最好要单独使用.换句话说,一旦使用public key,就要放弃密 码的登录方式.因为木桶的容积取决于最短的一截,密码登录的安全性太低
  • public key登录的方式,可以不用prompt用户输入密码的阶段,非常的方便
  • 创建public key的方式是ssh-keygen,需要注意的是,默认生成key的文件夹是~/.ssh,里 面有两个文件:
    • ~/.ssh/id_rsa:这个是私钥,不能跟人分享
    • ~/.ssh/id_rsa.pub:这个是公钥,可以安全分享给你想要访问的远程机器,把这个文件 拷贝到远程机器的~/.ssh/authorized_keys就可以"凭借私钥访问"啦.一个方便的拷 贝公钥到对方authorized_keys的方法是ssh-copy-id
      $ ssh-copy-id -i ~/.ssh/id_rsa.pub <remote-host-ip-or-name>
      

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

  • 第一步肯定是安装软件了:
    • centos安装
      # yum install nfs-utils
      
    • debian按照
      # apt-get install nfs-kernel-server
      
  • 第二步是确保daemon服务进程的启动
    • centos
      # systemctl enable nfs-server
      
    • debian
      # systemctl enable nfs-kernel-server
      
  • 第三步就是更改配置文件:
    • 配置文件的位置在
      /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

  • 前面说过了,openssh这个软件包包括了sshfs,这是一个非常方便的工具,不需要像NFS一 样设置很多的东西,只要你可以ssh到某台机器,就可以mount它的文件夹到你本地
  • 虽然是openssh软件包的东西,但是不在openssh-server里面,通常需要额外安装
    # yum install epel-release && yum install sshfs
    # apt-get install sshfs
    
  • 一旦安装完以后,就可以利用这个命令sshfs来把remote的文件夹mount到你本地
    $ sshfs jay@10.10.10.101:/home/jay/docs /home/hfeng/mnt/docs
    
  • sshfs命令对于那种"需要远程机器上的文件,但不能一次又一次的remote登录上去的情 况"非常合适

Chapter 5: Monitoring System Resources