51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

Ubuntu Server 从入门到精通

Preface {#preface}

好多年前记的一篇流水账,有空会将里面的内容改改,拆分一下。

第 0 章 Ubuntu 18.04 新特性 {#第-0-章-ubuntu-1804-新特性}

0.1 简介 {#01-简介}

  • 2018年4月26日,Ubuntu Linux 18.04 LTS(Bionic Beaver)版正式发布
  • 长期支持版(5年支持期)
  • 下载地址
  • 升级
    • 16.04 LTS 暂不支持直接升级到18.04,到7月底可直接升级
    • 17.10先安装update-manager-core
    • do-release-upgrade

0.2 新特性 {#02-新特性}

0.2.1 新特性 {#021-新特性}

  • 4.15内核 支持新软硬件特性(CPU、MD、SATA、内核安全、软件)
  • OpenJDK 10 默认JRE/JDK(年底升级11)
  • 交换文件代替交换分区
  • 不再安装Python2,代之以Python 3.6
  • OpenSSH禁用小于1024位的RSA密钥
  • Subiquity服务器安装程序
  • LXD 3.0、QEMU 2.11.1、libvirt 4.0、Open vSwitch 2.9

0.2.2 安全改进 {#022-安全改进}

  • 更好的支持ASLR(随机内存地址),大部分进程都支持(少数例外)
  • Spectre、Meltdown补丁
  • 加强雷电设备安全控制

0.2.3 网络 {#023-网络}

  • ifconfig / ifup / ifdown
  • ip link set device up / ip link set device down
  • networkctl status / networkctl status $device

0.2.4 网络配置 {#024-网络配置}

  • /etc/netplan/*.yaml 替代了 /etc/network/interfaces

  • Renderer 读取/etc/netplan/*.yaml配置文件使之生效

    • NetworkManger 桌面系统的Renderer进程
    • systemd-networkd 服务器的Renderer进程
  • sudo vim /etc/netplan/*.yaml 编辑配置文件,服务器端

    # DHCP配置
    network:				# 网络配置
    	version: 2			# 版本
    	renderer: networkd	# Renderer配置
    	ethernets:			# 对以太网卡进行配置
            enp0s3:			# enp0s3的配置
            # yes/no,true/false都是ok的
            dhcp4: yes		# 自动获取ipv4地址
            dhcp6: yes		# 自动获取ipv6地址
    
    # 静态IP配置
    network:				# 网络配置
        version: 2			# 版本
        renderer: networkd	# Renderer配置
        ethernets:			# 对以太网卡进行配置
            enp0s3:			# enp0s3的配置
            dhcp4: false	# 关闭ipv4的DHCP自动配置
            dhcp6: false	# 关闭ipv6的DHCP自动配置
            addresses: [192.168.1.70/24]	# 配置ip地址,可写多个,用逗号隔开,记得后面要跟上子网掩码
            gateway4: 192.168.1.1			# 配置ipv4的网关
            nameservers:
            	addresses: [192.168.1.1, 8.8.8.8, 8.8.4.4]	# 配置DNS
    
    # 桥接配置
    network:				# 网络配置
        version: 2			# 版本
        renderer: networkd	# Renderer配置
        ethernets:			# 对以太网卡进行配置
            enp0s3:			# enp0s3的配置
            dhcp4: no		# 关闭ipv4的DHCP自动配置
            dhcp6: no		# 关闭ipv6的DHCP自动配置
        bridges:			# 桥接网卡配置
            br0:			# 给桥接网卡去个名字叫br0
            interfaces: [enp0s3]	# 将enp0s3这个物理网卡加入到逻辑的桥接网卡中
            # 配置桥接网卡DHCP或者静态IP,这里配置为静态IP
            dhcp4: no	# 关闭ipv4的DHCP自动获取,
            addresses: [192.168.1.2/24, '2001:1::2/64']	# 配置桥接网卡的IP
            gateway4: 192.168.1.1			# 配置ipv4的网关
            nameservers:
            	addresses: [192.168.1.1, 8.8.8.8, 8.8.4.4]	# 配置DNS
    
  • sudo vim /etc/netplan/*.yaml 编辑配置文件,桌面版

    network:
    	version: 2
    	renderer: NetworkManager	# 默认将所有配置的权限交给了NetworkManager
    
    # 桌面版Ubuntu网络配置(静态IP)
    network:
      version: 2
      ethernets:
      	ens33:
      		addresses: [192.168.2.247/24]
      		gateway4: 192.168.2.1
      		dhcp4: no
      		nameservers:
      			addresses: [192.168.2.247]
      		optional: true
    
  • 使网络配置生效

    • sudo netplan --debug apply 应用配置并显示应用的过程,便于排错
    • sudo netplan apply 直接应用配置
  • 查看网络配置是否生效

    • 命令:sudo networkctl status 显示当前网络信息

0.3 ip命令 {#03-ip命令}

0.3.1 ip link {#031-ip-link}

  • ip link set enp0s3 up 启用enp0s3网卡
  • ip link set enp0s3 down 禁用enp0s3网卡
  • ip -s -s -d link ls enp0s3 查看enp0s3网卡的详细信息
  • ip link set dev enp0s3 mtu 1500 修改enp0s3网卡的MTU
  • ip link set dev enp0s3 address 00:11:22:33:44:55 修改enp0s3网卡的MAC地址

0.3.2 ip addr {#032-ip-addr}

  • ip addr / ip addr show 列出所有网卡信息
  • ip addr add dev enp0s3 192.168.1.1/24 对enp0s3网卡添加一个ip
  • ip addr del dev enp0s3 192.168.1.1/24 将enp0s3网卡删除掉一个ip
  • ip addr flush dev enp0s3 将enp0s3网卡设备的ip给清掉

0.3.3 ip route {#033-ip-route}

  • ip route show 查看路由信息
  • ip route get 1.1.1.1 查看去往1.1.1.1这个ip时,使用的是路由表中的哪一项
  • ip route add default via 192.168.1.1 加一个默认路由(网关)
  • ip route add dev wlp3s0 10.0.0.0/8 via 192.168.1.1 加一个定向路由,去往10.0.0.0/8都由192.168.1.1这个ip且由wlp3s0这个网卡进行转发

0.3.4 ip maddress {#034-ip-maddress}

  • ip maddress 查看所有网卡的组播地址
  • ip maddress ls enp2s0 查看enp2s0网卡的组播地址
  • ip maddr add 33:33:00:00:00:01 dev enp2s0 对enp2s0网卡再添加到33:33:00:00:00:01这个组播地址

0.3.5 ip monitor {#035-ip-monitor}

  • ip monitor all 监视网络中ip地址的变化

0.3.6 ip neigh {#036-ip-neigh}

  • ip neigh 查看arp缓存
  • ip -s -s neigh show 查看arp缓存,详细
  • ip neigh add dev wlp3s0 192.168.123.100 lladdr 00:11:11:11:11:11 nud perm 通过wlp3s0网卡添加192.168.123.100绑定的00:11:11:11:11:11MAC地址,nud perm表示永久有效

0.4 基本配置 {#04-基本配置}

0.4.1 设置语言为中文 {#041-设置语言为中文}

  1. 安装简体中文语言包 ,命令:sudo apt install language-pack-zh-hans

    • 命令:sudo apt install language-pack-zh-hant 安装繁体中文语言包
  2. 查看系统中已安装的语言项 ,命令:locale -a 必须要有zh_CN.utf8这是简体中文语言项

  3. 编辑系统环境变量 ,命令:sudo vim /etc/environment 在最下方添加

    LANG="zh_CN.UTF-8"
    LANGUAGE="zh_CN:zh:en_US:en"
    

0.4.2 设置网桥 {#042-设置网桥}

  1. 安装网桥工具 ,命令:sudo apt install bridge-utils

  2. 编辑配置文件,命令:sudo vim /etc/netplan/01-network-manager-all.yaml

    # Let NetworkManager manage all devices on this system
    network:
      version: 2
      renderer: NetworkManager
      ethernets:
        ens33:			# 关闭dhcp让网卡没有ip地址
          dhcp4: no
          dhcp6: no
      bridges:			# 配置网桥
          br0:
            interfaces: [ens33]	# 让网卡通过网桥上网
            dhcp4: no
            addresses: [192.168.2.247/24]
            gateway4: 192.168.2.1
            nameservers:
              addresses: [8.8.8.8,8.8.4.4]
    
  3. 使配置生效 ,命令:sudo netplan apply

第 1 章 系统安装 {#第-1-章-系统安装}

1.1 基本安装(虚拟机中安装) {#11-基本安装虚拟机中安装}

1.1.1 下载地址 {#111-下载地址}

Ubuntu Server 17.04下载地址

1.1.2 安装步骤 {#112-安装步骤}

  1. 首先在virtualbox中创建一个ubuntu的虚拟机
    • 分配了1G的内存
    • 分配了40G的硬盘空间
  2. 在virtualbox设置中的存储选择Ubuntu Server的iso文件然后启动虚拟机进入到安装界面
  3. 安装过程

1.2 高级安装(RAID) {#12-高级安装raid}

1.2.1 RAID介绍 {#121-raid介绍}

RAID (Redundant Array of Independent Disks) 廉价冗余磁盘阵列

  • 磁盘阵列是由很多价格较便宜的磁盘,组合成一个容量巨大的磁盘组,利用个别磁盘提供数据所产生加成效果提升整个磁盘系统效能。
  • 利用这项技术,将数据切割成许多区段,分别存放在各个硬盘上。

1.2.1.1 硬RAID {#1211-硬raid}

  • 需要在物理的服务器中插上一块RAID的板卡,通过这块板卡来对磁盘进行管理,操作系统看来只有一个磁盘驱动器(和单个硬盘一样),而RAID板卡上一般都有自己的CPU,内存和管理软件等,所有关于RAID的管理、维护、容错等机制都是由RAID板卡完成的,所以是不占用系统的资源的,一般来说硬件RAID卡的性能是最好的。

  • 优点:

    • 对CPU 的占用率以及整体性能是这三种类型中最优势的
    • 有硬盘丢失时可以实现重建,如果RAID卡损坏时也可以更换RAID卡
  • 缺点:

    • 设备成本是三种类型中最高的
    • 需要有一定技术知识

1.2.1.2 软RAID {#1212-软raid}

  • 由操作系统实现的软件的RAID,操作系统可以知道每一块硬盘,可以直接管理和使用它们。
  • Windows和Linux系统都可以实现软件的RAID,但是两种的RAID是不相互兼容的,打个比方说如果装了双系统在Windows或Linux中实现软件的RAID,那么在Linux或Windows中之前做好的RAID就会消失或者发生错误
  • Linux中是基于mdadm驱动来实现软件的RAID

1.2.1.3 FakeRAID {#1213-fakeraid}

  • 假RAID,不是一个完整的RAID的实现,一般是个人用户,工作站,低端服务器安装了多操作系统想要使用RAID的情况才使用这个,现在已经很不常见了
  • 结合Bios设置、多通道控制器、软件驱动显示RAID的方法
  • 操作系统管理RAID,适用于多系统,性能弱于软RAID

相关链接百度百科 CSDN

1.2.2 RAID分类 {#122-raid分类}

1.2.2.1 RAID 0(条带卷) {#1221-raid-0条带卷}

  • 不限制硬盘的个数,它会将数据分块然后逐一的写入到每一块硬盘上,它的磁盘利用率是100%,因为它会将一个数据分成n份存储到每一块硬盘上,所以是没有容错机制的,如果某一块硬盘坏了就会缺少 1/n的数据(n为总硬盘的个数),而且剩下的数据也是不完整的,也没有用了。
  • 好处是可以同时向每一块硬盘读写数据,一个由 n 块磁盘组成的 RAID0 ,它的读写性能是单个磁盘性能的 n 倍,但由于总线带宽等多种因素的限制,实际的性能提升低于理论值。
  • 例如有2块硬盘组成RAID 0,将存储的数据分成了4份,那么第一份数据写入到第一块硬盘,第二份数据写入到第二块硬盘,第三份数据写入到第一块硬盘,第四份数据写入到第二块硬盘。

1.2.2.2 RAID 1(镜像卷) {#1222-raid-1镜像卷}

  • 只能由两块相同的硬盘组成,它将数据完全一致地分别写到工作磁盘和镜像磁盘,它的磁盘空间利用率为 50% 。 RAID1 提供了最佳的数据保护,一旦工作磁盘发生故障,系统自动从镜像磁盘读取数据,不会影响用户工作。

1.2.2.3 RAID 5(带奇偶校验的条带卷) {#1223-raid-5带奇偶校验的条带卷}

  • 至少要有3块硬盘组成,RAID5的磁盘上同时存储数据和校验数据,数据块和对应的校验信息存保存在不同的磁盘上,当一个数据盘损坏时,系统可以根据同一条带的其他数据块和对应的校验数据来重建损坏的数据。与其他 RAID 等级一样,重建数据时, RAID5 的性能会受到较大的影响。磁盘利用率为(n-1)/n(n为总磁盘个数)。
  • 例如在向4块硬盘组成的RAID5写数据时,将数据ABCD都分为三份来进行存储,则硬盘一存储A1,硬盘二存储A2,硬盘三存储A3,硬盘四存储奇偶校验值,然后硬盘一存储B1,硬盘二存储B2,硬盘三存储奇偶校验值,硬盘四存储B3,接着硬盘一存储C1,硬盘二存储奇偶校验值,硬盘三存储C2,硬盘四存储C3,最后硬盘一存储奇偶校验值,硬盘二存储D1,硬盘三存储D2,硬盘四存储D3。假设硬盘3发生故障,那么A3可以通过A1,A2,和相应的奇偶校验值来算出来,相对应C2可以通过C1,C3,和相应的奇偶校验值来算出来,D2可以通过D1,D3,和相应的奇偶校验值来算出来,数据B只是存储奇偶校验值得硬盘损坏,数据本身是完整的。所以RAID5同时只可以损坏一块硬盘,是无法通过奇偶校验值和一份数据算出另外两份数据的。

1.2.2.4 RAID 6(双奇偶校验的条带卷) {#1224-raid-6双奇偶校验的条带卷}

  • 至少要有4块硬盘组成,在RAID5的基础上再加一个奇偶校验值,磁盘利用率为(n-2)/n(n为总磁盘个数),最多可以同时损坏两块硬盘。

1.2.2.5 RAID 01 / 10(0+1 / 1+0) {#1225-raid-01--1001--10}

  • RAID 01和RAID 10都是RAID 0和RAID1两种方式的组合,并不是一种全新的RAID技术

  • RAID 01

    RAID01 是先做条带化再作镜像,本质是对物理磁盘实现镜像,RAID01 兼备了 RAID0 和 RAID1 的优点,它先用两块磁盘建立镜像,然后再在镜像内部做条带化。 RAID01 的数据将同时写入到两个磁盘阵列中,如果其中一个阵列损坏,仍可继续工作,保证数据安全性的同时又提高了性能。 RAID01 和 RAID10 内部都含有 RAID1 模式,因此整体磁盘利用率均仅为 50% 。

  • RAID 10

    RAID10 是先做镜像再作条带化,是对虚拟磁盘实现镜像。相同的配置下,通常 RAID01 比 RAID10 具有更好的容错能力。

1.2.3 Degraded {#123-degraded}

  • 当软RAID中有磁盘损坏时,将磁盘阵列置为降级状态,对性能有比较明显的影响,尤其是RAID5

1.2.4 Spare {#124-spare}

  • 备份盘,平时什么也不做,当有某一块硬盘损坏时,这个Spare盘就会立刻顶上,可以不分配Spare盘,也可以分配多块Spare盘

1.2.5 实际操作 {#125-实际操作}

1.2.5.1 准备工作 {#1251-准备工作}

  1. 新建一个Ubuntu 64位的虚拟机

  2. 在设置-->存储 给新建的虚拟机新增5块虚拟硬盘,加上创建时的一块,总共有6块硬盘,大小全部分配20G

  1. 启动虚拟机安装系统至磁盘分配步骤,将每个硬盘都创建出空白分区表

  1. 然后将你想要作为RAID的硬盘分出你希望大小的分区,如果是整个硬盘(一块)的空间都要当做RAID那么创建完空白分区表就可以了,RAID时会自动将整个硬盘分为1个区

1.2.5.2 RAID0 {#1252-raid0}

1.2.5.3 RAID1 {#1253-raid1}

1.2.5.4 RAID5 {#1254-raid5}

1.2.5.5 RAID6 {#1255-raid6}

1.2.5.6 RAID 0/1 {#1256-raid-01}

1.2.5.7 注意(重要) {#1257-注意重要}

1.3. 磁盘管理 {#13-磁盘管理}

1.3.1 LVM介绍 {#131-lvm介绍}

  • LVM是 Logical Volume Manager(逻辑卷管理)的简写,它是Linux环境下对磁盘分区进行管理的一种机制。

  • LVM可以动态的随时扩容和缩减存储的空间大小,当业务需求增大时,存储空间不足就可以在LVM的卷上直接新增硬盘或RAID动态的增加现有空间的大小,当业务缩减用不了那么多存储空间时,就可以将LVM卷上多余的硬盘或RAID拿下来另做它用以节省开支。

  • 由一个或多个物理硬盘分区或者RAID分区组成

  • 可继续扩展,灵活性高

1.3.1.1 Physical Volume(PV) {#1311-physical-volumepv}

  • 物理卷,指磁盘分区或从逻辑上与磁盘分区具有同样功能的设备(如RAID),是LVM的基本存储逻辑块,但和基本的物理存储介质(如分区、磁盘等)比较,却包含有与LVM相关的管理参数。
  • 物理硬盘、物理分区、软硬RAID都可以构成Physical Volume
  • LVM存储数据还是要存储到物理设备上的,所以最终是由Physical Volume来组成LVM

1.3.1.2 Volume Group(VG) {#1312-volume-groupvg}

  • 由一个或者多个PV构成,可扩展和收缩
  • 可进而被分割为Logical Volume(LV)
  • VG只是一个逻辑的组合体,最终当我们使用卷,在卷里面存储文件,需要吧VG进行一个划分,划分成Logical Volume(逻辑卷)

1.3.1.3 Logical Volume(LV) {#1313-logical-volumelv}

  • 类似于普通硬盘对应的分区概念
  • LV可格式化为具体的文件系统,也必须格式化为具体的文件系统格式才能使用,例如EXT4

1.3.1.4 Physical extent(PE 了解) {#1314-physical-extentpe-了解}

  • 组成PV大小的基本单元
  • 具有唯一的编号
  • 是可以被LVM寻址的最小单元
  • PE的大小是可配置的,默认为4MB

1.3.1.5 Logical extent(LE 了解) {#1315-logical-extentle-了解}

  • 逻辑卷的划分称为LE最小的、最基本的数据存储单位
  • 在同一个卷组中,LE的大小和PE是相同的,并且一一对应

1.3.1.6 分区原则(最佳实践) {#1316-分区原则最佳实践}

  • 为 /boot 、swap、/ 创建标准分区而不要创建为LVM,可以创建成RAID
  • 存储数据的分区才创建为LVM

1.3.2 实际操作 {#132-实际操作}

1.3.2.1 准备工作 {#1321-准备工作}

  1. 新建一个Ubuntu 64位的虚拟机

  2. 在设置-->存储 给新建的虚拟机新增5块虚拟硬盘,加上创建时的一块,总共有6块硬盘,大小全部分配20G

  1. 启动虚拟机安装系统至磁盘分配步骤,将每个硬盘都创建出空白分区表

1.3.2.2 LVM配置 {#1322-lvm配置}

计划

  • 分别从第一和第二块硬盘划出1G大小的空间组成RAID1,挂载boot分区(划分的RAID分区要开启Bootable flag)
  • Ubuntu17.04已经不需要swap分区了,取而代之的是swap文件,所以不为swap分区
  • 将第1,2硬盘剩余的空间再组成RAID1,将第3,4,5块硬盘组成RAID5,将RAID1和RAID5的use as都改为LVM的PV,将第6块硬盘的全部空间作为LVM的PV,最后将这三个组成为一个LVM的卷组
  • 基于卷组来创建逻辑卷

操作步骤

1.4 磁盘加密 {#14-磁盘加密}

1.4.1 介绍 {#141-介绍}

硬盘加密,是指将计算机用户的硬盘进行加密,防止信息泄漏。假如笔记本等设备丢了或被盗了,别人也无法获取你的硬盘中的数据。

1.4.2 LUSK {#142-lusk}

**LUSK:**Linux Unified Key Setup

  • 不依赖于操作系统的磁盘分区加密规范
  • 后端加密方法dm-crypt(ubuntu18.04只有这一种)

1.4.3 加密算法 {#143-加密算法}

  • aes
  • serpent
  • blowfish
  • twofish

1.4.4 注意事项 {#144-注意事项}

  • /boot分区不能加密,因为连boot分区都加密的话就无法引导系统开机了
  • 普通分区、RAID、LVM都能够进行加密

1.4.5 实际操作 {#145-实际操作}

第 2 章 命令行基础 {#第-2-章命令行基础}

2.1 shell介绍 {#21-shell介绍}

2.1.1 shell是什么 {#211-shell是什么}

  • shell是一个命令解释器,它在操作系统的最外层,负责直接与用户对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出结果,输出到屏幕返回给用户。这种对话方式可以是交互的方式(从键盘输入命令,可以立即得到shell的回应),或非交互(脚本)的方式。换句话说,Shell是一个命令行解释器,它为用户提供一个像Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell来启动,挂起,停止甚至是编写一些程序。

  • 用于运行系统指令的程序

  • shell中运行的多条系统指令可形成shell脚本

  • Bourne Shell(贝尔实验室发明)是最早的shell

  • Bourne-again:Bash(Ubuntu默认采用)是在Bourne Shell基础上增强功能

  • 通常成为终端

2.1.2 命令提示符 {#212-命令提示符}

  • name@host:path$

    • name:登录用户名
    • @:普通连接符
    • host:主机名
    • path:当前工作路径(~代表当前用户主目录)
    • $:代表普通用户(相对root用户)
  • name@host:path#

    • name:登录用户名(root)
    • @:普通连接符
    • host:主机名
    • path:当前工作路径(~代表当前用户主目录)
    • #:代表root用户(相对普通用户)

2.1.3 输入输出 {#213-输入输出}

  • 进程通过输入输出流读写数据
  • 默认标准输入输出称为stdin / stdout
    • 输入方式:文件、设备、终端、另一个进程的I/O
    • 输出方式:文件、设备、终端、另一个进程的I/O
  • 标准错误输出流 stderr
    • 运行出错时的提示
  • Ctrl-D 结束当前输入
  • Ctrl-C 无论当前情况如何,强制结束运行

2.2 基本命令 {#22-基本命令}

2.2.1 cat {#221-cat}

  • cat --- 查看文件内容

    • 查看单个文件

    • 查看多个文件(合并显示)

2.2.2 ls {#222-ls}

  • ls --- 列出当前目录内容
    • -l 显示详细内容(权限、inode、属主、属组、大小、修改时间mtime)
    • -a 包括隐藏的所有内容
    • -d 只显示目录自身信息
    • -i 显示inode信息
    • -S 按文件大小排序(默认按字母的顺序排序)
    • -r 倒序排列
    • -t 按修改时间排序
    • -h 文件大小以人类便于阅读的方式显示
    • --sort=key 排序
      • -r 反向排序
      • size 按大小
      • time 按时间
      • extension 按扩展名

  • ll == ls -la

2.2.3 cp {#223-cp}

  • cp --- 拷贝
    • cp file1 file2
    • cp file1 file2 dir/
    • -R/r 拷贝目录及其中全部内容
    • -l 硬链接拷贝(复制inode,inode相同)
      • 如果原本文件删除了也可以正常访问数据
    • -s 软链接拷贝(类似windows的快捷方式)
      • 如果原本文件删除了就无法访问数据了
    • -S 目标名称添加后缀
    • -u 源比目标新时才拷贝

2.2.4 mv {#224-mv}

  • mv --- 移动
    • mv file1 file2 dir/
    • -f 强制移动、覆盖目标

2.2.5 touch {#225-touch}

  • touch --- 创建一个空文件
    • 若文件存在,修改文件mtime,但不修改内容
    • touch filename

2.2.6 rm {#226-rm}

  • rm --- 删除
    • rm filename(删除单个文件)
    • rm -rf dir(递归删除,删除目录和目录下的所有文件和目录)
    • -i 每删除前提醒
    • -d 删除空目录

2.2.7 echo {#227-echo}

  • echo --- 将命令的参数显示在stdout
    • echo hello world!
    • -n 显示结束不换行
    • -e 结解释反斜线转义符
      • echo \"n\"
      • echo -ne 123\\b
    • echo $HOME

2.2.8 cd {#228-cd}

  • cd --- 切换目录
    • cd(后面什么不要加,回到当前用户主目录)
    • cd dirname

2.2.9 pwd {#229-pwd}

  • pwd --- 显示当前工作完整路径
    • 适用于提示符不显示完整路径
    • -P 物理路径(显示软链接对应的真实路径)
    • -L 逻辑路径(显示软链接自身路径)

2.2.10 mkdir {#2210-mkdir}

  • mkdir --- 创建目录
    • mkdir dirname
    • -p 一次性创建多层目录

2.2.11 rmdir {#2211-rmdir}

  • rmdir --- 删除空目录
    • -p 删除多层空目录

2.2.12 通配符 {#2212-通配符}

  • * 表示任意多个字符
  • ? 表示任意一个字符

2.2.13 grep {#2213-grep}

  • grep
    • grep root /etc/passwd 查看passwd文件中所有包含root的行
    • grep r* /etc/passwd 查看passwd文件中所有包含r的行
    • grep root /etc/* 显示etc下所有文件中包含root的行(目录不能grep)
    • -i 忽略大小写
    • -v 反向匹配
    • -n 显示行号
    • -r 递归目录及子目录中的所有文件
    • -c 显示目标文件中包含关键字的行数
    • grep -f 1.txt a.txt 多个关键字同时匹配,1.txt为包含关键词的文件(多个关键词)
    • grep a[123] a.txt 在a.txt中同时搜索a1、a2、a3
    • grep -E '1|2|3' a.txt 在a.txt中搜索1或者2或者3

2.2.14 less {#2214-less}

  • less --- 显示文本文件的内容
    • more的增强版
    • less /usr/share/dict/words
  • 快捷键
    • z/b 向下/上翻一页
    • v 进入编辑模式
    • g/G 直接跳至第一行/最后一行(或第n行)
    • /word 向前搜索关键词
    • ?word 向后搜索关键词
    • n/N 正向/反向继续搜索关键词(输入关键词后再使用)
    • q 退出
  • grep root /usr/share/dict/words | less 通过管道命令和其他命令结合使用

2.2.15 nano {#2215-nano}

  • nano --- 超简单的文本编辑器
    • Ctrl + G 取得在线帮助(help)
    • Ctrl + X 离开nano软件,若有修改过文件会提示是否需要保存
    • Ctrl + O 保存文件,如果有权限的话就能够保存文件
    • Ctrl + R 从其他文件读入数据,可以将某个文件的内容贴在本文件上
    • Ctrl + W 查询字符串,这个也是很有帮助的命令
    • Ctrl + C 说明目前光标所在处的行数与列数的信息
    • Ctrl + _ 可以直接输入行号,让光标快速移动到该行
    • Alt + Y 校正语法功能开启或关闭(单击开,再单击关)
    • Alt + M 可以支持鼠标来移动光标的功能

2.2.16 head / tail {#2216-head--tail}

  • head / tail --- 显示文件头部 / 尾部内容
    • 默认显示10行
    • -n n是指定显示的行数数值
  • head -3 /etc/passwd
  • tail -f /var/log/dmesg
    • -f 实时的显示文件中的内容
    • tailf 和tail -f xxx作用相同

2.2.17 diff {#2217-diff}

  • diff --- 比较文本文件
    • diff a b
      • a -add 文件2比文件1多;c -change 内容不同;d -delete 文件1比文件2多
      • 无返回结果表示两个文件内容相同
    • -u 统一格式输出
      • --- 表示文件1,+++ 表示文件2
      • 逗号分割的数字表示文件起止行号
    • -y 并排输出比较
      • | 表示不同
      • < 文件1比文件2多
      • > 文件2比文件1多
      • 配合-W使用,-W表示比对时每一行占多少个字符
    • -w 忽略空格
    • -i 忽略大小写
  • diff a/ b/ 比较文件夹
    • 比较目录结构,显示不同的文件名和目录
    • 如果两个目录下有同名文件,就会比对这两个文件的内容

2.2.18 file {#2218-file}

  • file --- 检测文件格式
    • 空文件或特定数据格式的文件
  • 顺序执行三种测试集
    • filesystem:匹配系统头文件<sys/stat.h>
    • magic:匹配文件头部魔术值,-l 参数查看所有魔法值
    • language:匹配文件起始的字符类型,ASCII,UTF-8
    • 一种测试匹配成功即停止检测,全都不匹配返回data
  • -f 文件列表文件
  • -b 只显示摘要信息
  • -ib 显示mime类型

2.2.15 find / locate {#2215-find--locate}

  • find / locate --- 查找文件
  • locate 基于文件索引进行搜索
    • 每隔一段时间,linux系统就会自动扫描系统中的文件,然后存储到数据库中,locate就是在此数据库中查询数据
    • 不验证文件是否存在,速度快但结果不一定准确
    • updatedb手动更新索引
  • find 从硬盘查找文件
    • -name 后面接查找的名字
    • -type
      • b 块设备文件
      • d 目录
      • c 字符设备文件
      • p 管道文件
      • l 符号链接文件
      • f 普通文件
    • -user 根据所属用户查找,后面接用户名
    • 按时间查找,n是一个数字,n/-n,+n
      • -amin n 查找系统中最后N分钟访问的文件(从当前时间向前推n分钟,下同)
      • -atime n 查找系统中最后n*24小时访问的文件(从当前时间向前推n*24小时,下同)
      • -cmin n 查找系统中最后N分钟被改变文件状态的文件
      • -ctime n 查找系统中最后n*24小时被改变文件状态的文件
      • -mmin n 查找系统中最后N分钟被改变文件数据的文件
      • -mtime n 查找系统中最后n*24小时被改变文件数据的文件
    • find / -mtime +1 -mtime -20
    • -cnewer 后面接文件名,表示搜索比这个指定的文件要更新的文件

2.2.16 stat {#2216-stat}

  • stat --- 显示文件/文件夹详细信息包括MAC时间
    • Modify 文件的修改时间
    • Access 最后访问时间
    • Change 文件属性修改时间

2.2.17 sort {#2217-sort}

  • sort --- 排序
    • -r 反向排序
    • -n 按数值大小排序
    • -M 按月份排序
      • 'JAN' ------ 'DEC'
  • sort a.txt 将a.txt的内容排序

2.2.18 vi {#2218-vi}

  • vi --- 文本编辑
  • Linux所有对象都是文件
    • 运行中的文件称为进程
  • 所有服务器配置都是通过编辑文本配置文件来完成
    • vi、nano、emacs(无优劣之分)
  • vi的三种模式
    • 一般命令模式(默认)
      • 从编辑模式按 ESC / Ctrl + [ 进入
      • Ctrl + f 向文件尾翻一屏
      • Ctrl + b 向文件首翻一屏
      • ZZ 保存当前修改并退出
      • D 删除光标到行尾内容
      • dd 删除光标所在行全部内容
      • ndd 从光标所在行向后删除n行(包括当前行)
      • yy 复制光标所在行全部内容
      • nyy 从光标所在行向下复制n行内容
      • p 粘贴
      • /字符串 向前搜索关键字 n 跳入下一个符合的位置
      • ?字符串 向后搜索关键字 n 跳入下一个符合的位置
    • 命令模式
      • 从一般命令模式按 : 进入
      • 按 ESC 回到一般命令模式
      • :a, bs/A/B 从a行到b行搜索字符A并替换成B
        • :1,s/word1/word2/gc 全文范围内替换,代表尾行,g代表全局范围,c代表替换前确认一下
      • :5 光标跳至第5行首
      • :$ 光标跳至末尾行首
      • :wq 保存退出
      • :q! 不保存退出
      • :e b.txt 编译b.txt(可以自动补齐,多文件编辑模式)
      • :n 编辑下一个文件
      • :f 显示当前编辑的文件名和编辑信息
      • :set number 显示行号
      • :set nonumber 不显示行号
    • 编辑模式
      • 从一般命令模式按i、a、o进入
      • a 在当前光标后添加文本 A 在行末添加文本
      • i 在当前光标前插入文本 I 在行首插入文本
      • o 在光标当前行的下一行插入一空行 O 在光标当前行的上一行插入一空行

2.2.19 man/info {#2219-maninfo}

  • man/info --- 帮助文档
  • Linux系统有完善的文档体系,Manual是最主要的帮助
  • man cmd
  • man -k keyword 搜索关键词(不知道具体命令)
  • 每个命令的手册页,可以使用数字变化引用片段(section)
  • man 5 passwd(按section查看)
    • 1: 用户命令
    • 2: 系统调用
    • 3: 高级Unix编程库文档(程序员常用)
    • 4: 设备接口和驱动信息(很少使用)
    • 5: 文件描述(系统配置文件)
    • 6: Games
    • 7: 文件格式,惯例,编码(ASCII等)
    • 8: 系统命令和服务器
  • GUN项目不太喜欢man,因此开发了info
    • 有时候优于man,有时不是
    • info ls
  • /usr/share/doc 其他 一些帮助文档
  • command -h / --help 显示命令帮助

2.2.20 awk {#2220-awk}

  • awk --- 格式化文本信息
    • awk '{print $2}' 显示一行内第二列内容,默认以空格分割
    • awk -F: '{print $2}' 显示一行内第二列内容,并指定分割符为 :

2.2.21 sudo {#2221-sudo}

  • sudoer 出于安全的考虑sudo
  • 临时切换成root账户执行命令
  • visudo 命令,编辑sudo配置文件(/etc/sudoers)

2.3 进程管理 {#23-进程管理}

  • 进程就是运行中的程序文件
    • PID:进程ID
    • TTY:运行进程的终端设备
    • STAT:进程状态(S leep、Running)
    • TIME:该进程占用的CPU时间
    • COMMAND:命令名称
  • PS
    • -x 当前用户启动的所有进程
    • -ax 所有用户启动的进程
    • -u 进程详细信息
    • -w 显示进程文件完整路径
    • ps u PID ($$:当前shell的进程ID)
    • ps - L PID 查看进程下的线程
    • ps fjax 树型显示进程,包含PID
  • pstree 树型显示进程
  • 结束进程
    • kill pid 结束pid的进程,默认发送TERM指令
    • kill -STOP pid 暂停进程
    • kill -CONT pid 恢复已暂停的进程
    • kill - KILL pid(kill -9 pid) 暴力结束进程
    • kill -l 显示所有kill命令的指令

2.4 打包压缩 {#24-打包压缩}

2.4.1 gzip {#241-gzip}

  • Linux标准压缩程序 GUN Zip
  • gzip file 压缩,会删除原始文件
  • gunzip file 解压
  • Gzip不能做多文件或目录的归档打包

2.4.2 tar {#242-tar}

  • tar --- 打包归档(Archive)

  • tar cvf archive.tar file1 file2 ...

    • c 创建归档
    • v 详细诊断输出
    • f 此参数后面必须是归档文件名
    • x 解包
    • t 显示包里面的东西,不会解出来
  • gunzip file.tar.gz

  • tar tvf arch.tar 查看包内容

  • tar xvf file.tar 解包

  • tar xvf file.tar -p 保留原始权限

  • 降低磁盘和内核IO消耗(打包同时压缩)

    • zcat file.tar.gz | tar xvf -
  • zcat == gunzip -dc

    • -d 解压
    • -c 解压结果输出到stdout
  • tar ztvf file.tar.gz

    • z 自动调用gzip
    • .tgz == .tar.gz

2.4.3 bzip2 {#243-bzip2}

  • 另一个压缩程序 bzip2(.bz2)
    • 比gzip压缩速度慢,文本压缩比高(发布源码)
    • 解压 bunzip2
    • tar jcvf file.tar.bz2 file1 file2 ......
      • j 自动调用bzip2

2.5 命令行快捷键 {#25-命令行快捷键}

  • Ctrl + b 左
  • Ctrl + f 右
  • Ctrl + p 上
  • Ctrl + n 下
  • Ctrl + a 光标至行首
  • Ctrl + e 光标至行尾
  • Ctrl + w 删除光标前面以空格分割段落(内容)
  • Ctrl + u 删除光标到行首
  • Ctrl + k 删除光标到行尾
  • Ctrl + y 粘贴删除的内容

2.6 Shell 输入与输出 {#26-shell-输入与输出}

2.6.1输出重定向 {#261输出重定向}

  • command > a.txt 覆盖a.txt原来的内容
    • set -C 命令,禁止覆盖文件,防止误操作
  • command >> a.txt 向a.txt追加内容

2.6.2 标准输入重定向 {#262-标准输入重定向}

  • command < a.txt 将a.txt中的内容传递给command命令
  • head < /proc/cpuinfo == head /proc/cpuinfo

2.6.3 管道 {#263-管道}

  • head /proc/cpuinfo | tr a-z A-Z
  • ifconfig | grep inet | awk '{print 2}' | awk -F: '{print 2}'

2.6.4 标准错误 stderr(报错包含重要信息) {#264-标准错误-stderr报错包含重要信息}

  • ls /abcdefg 2 > e 2 是标准错误的标号,此命令表示将出错信息重定向到e文件,而不显示到屏幕
  • ls /asd > f 2>&1
    • 标准输出到f文件,标准错误输出到标准输出,所以最后标准输出和标准错误都会输出到f文件

2.6.5 常见报错信息 {#265-常见报错信息}

  • No such file or directory(查看不存在的文件目录)
  • File exists(创建与文件同名的目录)
  • Not a directory, Is a directory(把文件当目录)
  • No space left on device(磁盘空间不足)
  • Permission denied(权限不足)
  • Operation not permitted(杀掉不属于自己的进程)
  • Segmentation fault, Bus error(程序访问禁用内存)

2.7 FHS {#27-fhs}

2.7.1 简介 {#271-简介}

  • Filesystem Hierarchy Standard(文件系统层次化标准)的缩写,多数Linux版本采用这种文件组织形式,类似于Windows操作系统中c盘的文件目录,FHS采用树形结构组织文件。FHS定义了系统中每个区域的用途、所需要的最小构成的文件和目录,同时还给出了例外处理与矛盾处理。

2.7.2 目录和路径 {#272-目录和路径}

  • 相对路径
  • 绝对路径
  • . 代表当前目录
  • .. 代表当前目录的上层目录

| 目录 | 作用 | |:--------|:----------------------------------------------------------------------------------------| | / | 根目录,一台电脑有且只有一个根目录,所有的文件都是从这里开始的。 | | /bin/ | 基础的,用户级别指令存放位置, 二进制可执行命令文件 | | /boot/ | 存储操作系统启动、引导过程中的静态文件 | | /dev/ | 这里主要存放与设备(包括外设)有关的文件, 系统就是从这个目录开始工作的。另外还有一些包括磁盘驱动、USB驱动等都放在这个目录。 | | /etc/ | 主要存放系统配置方面的文件 | | /home/ | 这里主要存放你的个人数据。具体每个用户的设置文件,用户的桌面文件夹,还有用户的数据都放在这里。每个用户都有自己的用户目录,位置为:/home/用户名。当然,root用户除外。 | | /lib/ | 基本的,共享的库文件,以及内核模块 | | /media/ | 挂载外部存储,一般挂载移动存储类型的设备,例如u盘,光驱等 | | /mnt/ | 挂载外部存储,一般把临时的挂载,挂载到mnt | | /opt/ | 安装除操作系统软件之外的其他软件的时候,默认的安装目录 | | /sbin/ | 系统级别的可执行程序 | | /srv/ | 存放服务的数据 | | /tmp/ | 存放临时文件 | | /usr/ | 放置用户级别的工具和软件,子目录还有bin、sbin等也是存放用户和系统级别的可执行程序(历史遗留问题) | | /var/ | 存放经常变动的系统文件,例如系统日志文件,用户邮件等 | | /root/ | root用户的主目录 | | /proc/ | 系统启动过程中临时生成,关机后就没有了,是一个虚拟目录, 它是内存的映射,包括系统信息和进程信息 |

第 3 章 包管理 {#第-3-章-包管理}

3.1 介绍 {#31-介绍}

Linux发行版操作系统 ------ 大量软件包的集合

  • 内核、库文件、命令行shell、图形接口、其他应用软件包共同组成操作系统

3.1.1 包管理 {#311-包管理}

  • 简介

    • 安装、删除、更新、配置修改
    • 不同发行版的包管理不同
    • 库软件包提供其他软件的依赖
      • 减少内存硬盘用量,功能相同或相似的功能打包成一个软件包,不重复造轮子(所有软件依赖内核包)
      • 丢失或版本差异问题主要原因(一环出错,全部出错)
      • Linux的库文件 .so ,windows下的库文件 .dll
    • Windows是微软的,但Linux发行版太多
      • Linux发行版太多,每一个发行版的依赖都有所不同,而windows只有一个
      • 打造自己的软件仓库,维护独立的包依赖关系是发行版包管理的最大任务
  • 软件包

    • RPM、DEB(Ubuntu集成自Debian Linux)
      • 内含meta-data源数据,可以通过这个找到软件包中每一个文件的位置,用户名称,文件和软件包的归属等
      • 预编译的二进制程序文件(不是源码)
      • 配置脚本等
  • 包管理系统

    • Meta-data 提供追踪包中全部文件的能力
    • 维护已安装文件的数据库(包名称、归属及辅助信息)
    • 解决包依赖关系
    • 建议使用唯一的包管理系统

3.1.2 软件仓库 {#312-软件仓库}

  • 官方Repository
    • 打造封闭但有质量保证的软件包来源(苹果)
    • 慎用第三方软件仓库

3.2 Dpkg包管理器 {#32-dpkg包管理器}

3.2.1 介绍 {#321-介绍}

  • Dpkg本地包管理器
    • 安装、删除、创建deb包
    • 不依赖软件仓库、不能自动检索和下载软件包
    • 不判断和解决依赖关系,需要手动的安装依赖

3.2.2 查看、安装、卸载包 {#322-查看安装卸载包}

  • 查看查找包

    • dpkg -l 列出本地已安装的所有软件包
    • dpkg -L ufw 列出包在本地安装的所有文件
    • dpkg -S /etc/ufw 查找文件归属的软件包
  • 安装包

    • dpkg -i name_version_architecture.deb 安装一个包
      • /var/cache/apt/archives
  • 卸载包

    • dpkg -r name:arch 卸载包,不会删除配置文件,arch为架构,可以不加
    • dpkg -P name:arch 卸载包,且删除配置文件,arch为架构,可以不加

3.2.3 显示删除架构 {#323-显示删除架构}

  • 显示支持的架构
    • dpkg --print-architecture 架构(amd64、i386)
    • dpkg --print-foreign-architectures 显示系统支持的其他架构包
    • cat /var/lib/dpkg/arch 查看系统所有支持的架构
  • 删除dpkg支持的架构
    • dpkg --remove-architecture 删除一个支持的架构包
      • dpkg --remove-architecture i386 删除i386架构

3.3 APT包管理器 {#33-apt包管理器}

3.3.1 介绍 {#331-介绍}

  • UBuntu里首选的包管理器,推荐使用

  • 依赖官方的软件仓库

    • 安装、卸载、更新包括整个操作系统的所有软件(包括操作系统)
    • 更新索引、更新包、自动解决依赖关系

3.3.2 更新、安装、卸载 {#332-更新安装卸载}

  • 更新

    • sudo apt update 更新索引
      • /etc/apt/sources.list 文件,官方软件仓库源
      • /etc/apt/sources.list.d/ 目录,放置第三方软件仓库的源,其实也可以把源加入到官方源文件中,但是推荐在此目录下新建一个软件源文件
    • sudo apt upgrade 更新已安装的包(不会增加和删除包),即使加测出内核有新版本,也不会更新内核文件
    • sudo apt dist-upgrade 更新新包,删除旧包(包含内核
  • 安装包

    • sudo apt install nmap 安装包
      • sudo apt install nmap -y 安装包,不需要输入Y/n
  • 卸载包

    • sudo apt remove nmap 删除包,不会删除配置文件

    • sudo apt remove nmap --purge 删除包及其配置文件

      • sudo apt purge nmap 删除包及其配置文件

3.3.3 查看操作日志 {#333-查看操作日志}

  • apt更新,安装,删除等操作会保存在 /var/log/dpkg.log 此日志文件中

3.3.4 搜索、包描述、清理 {#334-搜索包描述清理}

  • 搜索

  • sudo apt search 'keywords' 搜索关键词

    • sudo apt search 'network mapper' 搜索网络扫描相关的包
  • 查看详细信息

    • sudo apt show nmap 显示完整的软件包描述
  • 清理

    • sudo apt autoremove 自动删除不需要的包
      • 慎用,更新内核时不会删除旧内核,软件在新的内核中可能不需要依赖这些包,但当新内核出现问题需要回退到旧内核时,就有可能需要依赖这些包了

3.3.5 下载、保存地址 {#335-下载保存地址}

  • 保存地址
    • 下载包的保存地址 /var/cache/apt/archives ,确定都安装后可以讲里面的文件删除
    • 更新索引文件的保存地址 /var/lib/apt/lists ,可用cat命令查看
  • 下载
    • apt download nmap 只下载安装包,会下载到当前目录下
    • apt source nmap 下载源码和安装包,会下载到当前目录下
      • apt showsrc nmap 查看源码相关的信息

3.3.6 自动更新 {#336-自动更新}

  • sudo apt install unattended-upgrades 安装无人值守升级包

  • 配置文件

    • /etc/apt/apt.conf.d/50unattended-upgrades 配置更新哪些类

    • /etc/apt/apt.conf.d/10periodic 配置更新周期

  • 重启服务

    • sudo systemctl restart unattended-upgrades.service
    • sudo service unattended-upgrades.service restart
  • 目录日志

    • /var/log/unattended-upgrades/
  • 自动更新通知

    • /etc/apt/apt.conf.d/50unattended-upgrades 配置文件中启用自动发送邮件功能

    • Apticron 挡自动更新出现问题或没有问题时发送邮件

      • sudo apt install apticron 安装Apticron

3.3.7 APT更新设置 {#337-apt更新设置}

  • 官方库
    • /etc/apt/sources.list
    • 注释掉cdrom源 光盘的软件包,安装完成会自动注释,如果没有注释就注释掉
    • 第一列:二进制安装包或源码包(deb/deb-src)
    • 第二列:软件仓库的URL地址
    • 第三列:操作系统codename
    • 第四列:库的内容构成、以及是否官方支持
      • Main 官方支持,包含源码,官方维护bug
      • Restricted 官方支持,非开源许可,官方维护bug
      • Universe 社区支持
      • Multiverse 既不开源也不支持,自己承担风险,通常不是安全更新
  • 第三方库
    • 存在安全风险,可能造成系统稳定性问题
    • 作为最后一种选择
    • 建议为每个第三方库创建独立的源.list文件
      • /etc/apt/sources.list.d/
    • 验证GnuPG Key
    • 删除GnuPG Key
      • 删除索引文件
      • 运行 apt-key del keyname 命令删除GnuPG Key
    • apt-key list 列出已保存在系统中key
    • apt-key update 更新本地trusted数据库,删除过期没用的key
  • PPA
    • Personal Package Archive(PPA) 个人的包归档服务器,针对个人软件作者,提供软件发布的源,官方提供服务器等
    • PPA本质上是另外一种形式的apt软件库
      • 适用于没有自建软件库的发布者
      • PPA中的软件没有经过官方审核
    • sudo apt-add-repository ppa:ondrej/mariadb-10.0 添加源
    • PPA主页:https://launchpad.net/ubuntu/
    • 删除PPA
      • 删除 PPA 源的命令格式则为:sudo add-apt-repository -r ppa:user/ppa-name
      • 然后进入 /etc/apt/sources.list.d 目录,将相应 ppa 源的保存文件删除
      • sudo apt-get update

3.4 SNAP包管理 {#34-snap包管理}

  • APT包管理器的缺点
    • 系统版本升级后应用软件库基本冻结,就是新版系统发布后旧版本就基本上不更新了
      • 老版本系统维持使用稳定版软件和库(旧版本)
    • 安全补丁除外
    • 为了维护一致的包和库的依赖关系无法安装最新版软件
  • SNAP包管理操作独立于软件仓库
    • 可分发不属于官方库的软件版本
    • 软件安装使用不受操作系统包和库依赖关系的影响
    • Snap包内建与Linux发行版不兼容的库
    • Snap还年轻,APT仍然是这个时代的霸主
  • 使用方法
    • sudo apt install snap 安装snap
    • sudo snap find nmap 查找软件包
    • sudo snap install nmap 安装软件包
    • sudo snap remove nmap 删除软件包
    • sudo snap refresh 更新索引
    • sudo snap refresh nmap 更新软件包
  • 同时安装多个软件包(彼此独立)
  • 作为APT的补充

第 4 章 存储管理 {#第-4-章-存储管理}

4.1 存储空间规划和查看 {#41-存储空间规划和查看}

4.1.1 存储 {#411-存储}

  • 硬盘是计算机中最主要的存储设备
  • 传统磁盘分区与逻辑卷管理
  • 事前合理规划很重要
  • 对磁盘的所有操作都要小心小心再小心

4.1.2 查看磁盘空间用量 {#412-查看磁盘空间用量}

  • df -h ------ 以人类方便观看方式的显示

    • 第一列:文件系统
    • 第二列:存储空间
    • 第三列:使用量
    • 第四列:可用量
    • 第五列:使用率
    • 第六列:挂载点

  • df -i ------ 显示inode信息

4.1.3 查看目录文件大小 {#413-查看目录文件大小}

  • sudo du 显示当前目录下目录占用空间信息

  • sudo du / 显示系统中所有的目录文件占用信息

  • sudo du -h 以人类方便观看方式的显示

  • sudo du -hcs *

    • 显示当前目录
    • -s 摘要
    • -c 汇总,在最后一行显示上方文件目录大小总和

  • ncdu

    • sudo apt install ncdu

    • ncdu 形象化的显示信息,不加参数默认显示当前目录信息

      • 上下箭头或鼠标滚轮移动光标,右箭头或回车进入选中目录,左箭头返回
      • ? 显示帮助信息
      • n 按名称排序
      • d 删除选中
      • t 先显示目录再显示文件
      • g 显示占用百分比,多按几次会有不同方式
      • q 退出程序
    • ncdu / 显示根目录下的所有信息,默认以大小排序

4.2 硬盘分区格式化 {#42-硬盘分区格式化}

4.2.1 添加硬盘 {#421-添加硬盘}

步骤

  1. 磁盘设备名称,都在dev目录下 ls /dev/sd?可以查看
    • /dev/sda、/dev/xdb、/dev/vdc
  2. 硬盘分区
    • sudo fdisk -l查看所有硬盘的大小,分区等信息
    • lsblk
  3. 文件系统格式Ext4、XFS(适用于大空间、多文件、数据库)
  4. 挂载/etc/fstab 自动挂载

4.2.2 硬盘分区 {#422-硬盘分区}

  • sudo fdisk /dev/sdb 为sdb设备分区

    • m 显示帮助菜单

    • MBR分区
      • 传统分区格式、最大四个主分区、最大分区2T容量限制
    • GPT分区
      • 未来标准、128个分区、单个分区无容量限制、推荐使用

创建GTP格式分区表3

创建MBR格式分区表

4.2.3 格式化分区 {#423-格式化分区}

  • sudo mkfs.ext4 /dev/sdb1 将sdb1分区格式化成ext4格式
  • sudo mkfs.xfs /dev/sdc1 将sdc1分区格式化成xfs格式

4.2.4 挂载分区 {#424-挂载分区}

  • /mnt、/media 可以将分区挂载才这些目录下,也可以自己手动创建一个目录来挂载
  • mount /dev/sdb1 /mnt/db1 将sdb1分区挂载到/mnt/db1目录下
  • mount /dev/sdb1 -t ext4 /mnt/db1 将sdb1分区挂载到/mnt/db1目录下,并指定分区格式为ext4,如果不指定的话也会自动检测的
  • umount /mnt/db1 卸载/mnt/db1目录下的挂载设备

自动挂载

  • 配置文件 /etc/fstab

    • 第一列:设备ID 分区的UUID、设备名也可,推荐选择唯一ID
    • 第二列:挂载点 swap无需挂载(填 none)
    • 第三列:文件系统 ext4、swap
    • 第四列:options defaults:rw、exec、auto、nouser、asynchronous
      • rw 可读写
      • exec 可执行
      • auto 随操作系统启动时,此分区会自动挂载
      • nouser 只有root用户才可以挂载此分区
      • asynchronous 往硬盘读写数据的时候时异步的方式
    • 第五列:dump 用于备份工具识别,1 备份、0 不备份
    • 第六列:pass FS错误时fsck是否检查错误,0 不查、1 优先、2 后查
    • UUID=176d22bc-dccd-41ec-8556-6107dc198cfd /storage ext4 default 0 2

  • lsblk -fP、blkid 查看分区的UUID等信息

  • mount -a 将/etc/fstab的所有内容重新加载

4.3 Swap分区管理 {#43-swap分区管理}

4.3.1 Swap介绍 {#431-swap介绍}

在系统的物理内存不够用的时候,把物理内存中的一部分空间释放出来,以供当前运行的程序使用。那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临时保存到Swap分区中,等到那些程序要运行时,再从Swap中恢复保存的数据到内存中。

  • 关于Swap的争论
    • 需要、不需要(Raspberry Pi)
    • 大小多少才合理(2-16G)
    • Swap文件、Swap分区
  • 理想状态下应该无事可做的Swap
    • 大量的Swap空间使用意味着服务器已疲于奔命
    • free -m 查看内存及Swap
  • 某些云主机默认没有Swap

4.3.1 Swap文件 {#431-swap文件}

  • 更改Swap的大小,创建一个新的Swap文件,让系统用这个新的Swap文件,老的Swap文件就可以删除了
  • sudo fallocate -l 2G /swaptest
    • -l 指定大小
  • sudo mkswap /swaptest 记下UUID,作为自动挂载的标识,或者也可以使用swaptest
  • sudo chmod 0600 /swaptest
  • sudo vim /etc/fastab
    • /swaptest none swap sw 0 0
  • swapoff -a / swapon -a

4.3.2 Swap分区 {#432-swap分区}

  • sudo fdisk /dev/sdb
    • 新建主分区,t修改分区表类型为82,w保存退出
  • sudo mkswap /dev/sdb1 将分区格式化成swap格式
  • sudo vim /etc/fstab 更改配置文件,设置开机自动挂载
    • UUID=200d67c5-864b-4799-b2f8-6167c8263335 none swap sw 0 0
  • sudo swapoff -a / sudo swapon -a

4.4 LVM管理 {#44-lvm管理}

4.4.1 简介 {#441-简介}

  • 无须重启计算机灵活调整硬盘空间大小
    • 硬盘分区太大浪费,太小无法满足业务发展需要
    • 将传统的硬盘分区逻辑的组合为资源池,按需分配
  • 概念
    • Volume Groups(池化,卷组)
    • Physical Volumes 物理卷
    • Logical Volumes(基本分区,RAID)
  • 安装包
    • sudo apt install lvm2

4.4.2 实际操作 {#442-实际操作}

  1. 创建物理卷

    • sudo pvcreate /dev/sdb 创建物理卷
    • sudo pvdisplay 查看物理卷
    • sudo pvscan / sudo pvs 显示物理卷摘要信息

  1. 创建卷组

    • sudo vgcreate vg01 /dev/sdb 创建一个卷组并添加一个PV到其中
    • sudo vgextend vg01 /dfanlajiyoujianev/sdc /dev/sdd 将sdc、sdd添加到vg01的卷组中
    • sudo vgdisplay 查看卷组
    • sudo vgscan / sudo vgs 显示卷组摘要信息

  1. 创建、扩大逻辑卷
  • sudo lvcreate -n lv01 -L 1G vg01
    • sudo lvdisolay
    • sudo lvscan / sudo lvs
  • sudo mkfs.ext4 /dev/vg01/lv01
    • sudo mount /dev/vg01/lv01 /mnt/lv01
    • df -h
  • sudo lvextend /dev/vg01/lv01 -l +256 增加256个PE(无 + 表示最终值
  • sudo lvextend /dev/vg01/lv01 -l +10%FREE 增加剩余空间(FREE)的10%
    • FREE 空余
    • VG vg的大小
    • LV 当前lv的大小
    • 更多使用 lvextend -h 查看
  • sudo lvextend /dev/vg01/lv01 -L +1G 增加1G的大小
  • sudo resize2fs /dev/vg01/lv01 将lv扩大的事通知给系统
    • df -h

  1. 缩小逻辑卷

    • sudo umount /dev/vg01/lv01 必须下线
    • sudo e2fsck -f /dev/vg01/lv01 检查文件系统
    • sudo resize2fs /dev/vg01/lv01 1G 缩小文件系统,为1G,不是减少1G
    • sudo lvresize /dev/vg01/lv01 -L 1G 缩小逻辑卷
    • 重新挂载查看

4.4.3 快照 {#443-快照}

  1. 介绍
  • 故障时可回退
  • 临时机制,不可视为备份
    • 本地保存,安全性无法保证
  • 系统根目录使用快照可用于测试补丁更新
    • 测试完成合并并删除快照
  • 创建快照等同创建一个新的LV
    • 初始不占空间,但文件发生修改时原块数据被拷贝到快照LV中
    • 回退时将快照中原始数据覆盖当前快照已被修改的 块
  1. 创建快照

    • sudo lvcreate -s -n s01 -L 1G vg01/lv01 创建新快照
    • 快照LV可直接被卸载,用于恢复单个文件
  2. 恢复快照(恢复后快照被删除)

    • sudo lvconvert --merge vg01/s01 将快照s01中的内容恢复,但是会提示将在下一次 activation 时恢复,所以要重新 activation
    • sudo umount /mnt/lv01 卸载
    • sudo lvchange -an vg01/lv01 更改成inactive状态
    • sudo lvchange -ay vg01/lv01 更改成ACTIVATE状态,此时就恢复快照中的内容了
    • sudo mount /dev/vg01/lv01 /mnt/lv01/ 重新挂载

4.4.4 移动物理卷数据 {#444-移动物理卷数据}

  • 当磁盘性能或老旧等因素需要更换硬盘,提前转移其中数据
  • sudo pvmove /dev/sdb 移动数据,让lvm自己选择移动到哪
  • sudo pvmove -n lv01 /dev/sdb /dev/sdc -i 1 只移动sdb上lv01到sdc上,-i表示1秒钟显示处理结果,sdc得是空的要不然原本数据没了,移动完成sdb lv01中的就没了

4.5 RAID高级管理 {#45-raid高级管理}

4.5.1 创建软RAID {#451-创建软raid}

  • 软RAID基于mdadm驱动实现

  • sudo apt install mdadm 安装mdadm

  • sudo mdadm -C -v /dev/md0 -l1 -n2 /dev/sdb /dev/sdc -z100M -x1 /dev/sdd 创建RAID

    • -C 创建
    • -v 显示创建过程中详细信息
    • -l RAID类型(0、1、2、5、6、10)
    • -n RAID盘数量
    • -z 从每个硬盘占用多少空间创建RAID,如果准备使用全部空间就不用指定此参数
    • -Z 指定RAID的总大小,自动计算,然后从每块硬盘上划空间
    • -x Spare盘

4.5.2 常用管理命令 {#452-常用管理命令}

  • cat /proc/mdstat 查看RAID信息

  • sudo mdadm -D /dev/md0 查看RAID的具体信息

  • sudo mdadm -E /dev/sdc 查看组成RAID的设备信息和RAID的信息

  • sudo mdadm -r /dev/md0 /dev/sda 从RAID组成中删除sda设备,如果不给删除则用 -f 将其设为失效再删除

  • sudo mdadm -a /dev/md0 /dev/sda 增加物理硬盘,替换刚刚删除的设备,如果之前有Spare盘顶上,则新增的会成Spare盘

  • sudo mdadm -A /dev/md0 手动让RAID之间数据同步

  • sudo mdadm -f /dev/md0 /dev/sdb 将磁盘置为失效,如果有Spare盘则会顶上

  • sudo mdadm --re-add /dev/md0 /dev/sdc 将 faulty 状态的设备重新加入(原本就在RAID组合中)

  • 替换硬盘后安装Grub

    • 如果引导盘坏了,需要运行下面的命令来安装引导文件,RAID不会同步引导文件
    • sudo grub-install /dev/md0
  • 格式化和挂载

    • sudo mkfs.ext4 /dev/md0 RAID就当一个普通分区来用就行了

4.5.3 链接 {#453-链接}

  • 符号链接(软链接)和硬链接
    • ls -li 查看文件和目录的inode值
    • inode:存放文件元数据的数据对象,表现为一个数值编号
  • 创建硬链接
    • ln fileS fileD
    • 目录不能创建硬链接
    • 不能移动硬链接到不同硬盘上(inode改变,不同硬盘都有自己的inode)
  • 创建软链接
    • 不共用inode
    • ln -s fileS fileD(相对路径和绝对路径)
      • 建议使用绝对路径
      • ln -s 1.txt /bak/l1.txt 如果这样写,l1.txt链接的是/bak/下的1.txt,用的是相对路径

4.6 磁盘加密 {#46-磁盘加密}

  • 清除所有数据
    • sudo dd if=/dev/zero of=/dev/sdc
  • 磁盘加密
    • sudo apt install cryptsetup
    • sudo cryptsetup luksFormat /dev/sdc1 对分区进行加密
    • sudo cryptsetup luksOpen /dev/sdc1 mycryptdisk 打开加密的分区
      • mycryptdisk是打开之后访问的名字,随便起,成功打开之后会生成mycryptdisk新的设备文件,通常情况下是在mapper目录下
    • sudo mkfs.ext4 /dev/mapper/mycryptdisk 格式化成ext4文件格式
    • sudo mount /dev/mapper/mycryptdisk /mnt/mycryptdisk 挂载
    • sudo chown study:study /mnt/mycryptdisk 更改所有者,这样在图形化界面就能操作里面的内容了,要不然得需要在命令行中用sudo才行
    • sudo cryptsetup luksClose mycryptdisk 关闭加密的分区

第 5 章 网络基础 {#第-5-章-网络基础}

5.1 网络 {#51-网络}

  • 为实现资源共享,彼此互联的多个计算设备就形成了网络
  • 为实现通信,设备间必须遵守相同通信协议
    • TCP/IP协议族
    • 标识彼此地址(ip),收发和处理相同约定的数据包
    • 分组交换即包交换网络
      • 分层头部、数据
    • 速度由频率决定
  • 网络分层
    • 物理层、网络(internet)层、传输层、应用层
    • 将复杂的问题分解为多层的简单问题,层间遵守相同接口

5.2 网卡配置 {#52-网卡配置}

5.2.1 网卡接口 {#521-网卡接口}

  • enp2s0、eth0、wlp3s0
    • wl:表示无线网卡
    • en:Ethernet 以太网
    • p2:p表示总线的编号,2表示2号编号
    • s0:表示连接在这个总线上的第0个网卡设备
  • ifconfig -a 查看所有网卡(包括未启用的)的信息,ip地址等
  • ip link / ipaddress 查看网卡和信息
  • sudo lshw -class network 查看网卡相关的信息,硬件信息
    • lshw 查看硬件相关的信息命令

5.2.2 管理网卡 {#522-管理网卡}

  • sudo ethtool enp0s3 查看网卡信息,速率等
  • sudo ethtool -s duplex half(full) speed 1000 修改网卡配置 {#ethtool}
    • duplex half 半双工
    • duplex full 全双工
    • -s speed 1000 速率修改为1000

5.2.3 网卡配置文件 {#523-网卡配置文件}

  • sudo vi /etc/network/interfaces

    • 动态获取IP地址

      • auto enp0s3 随操作系统启动而启动,自动启动,enp0s3为网卡名
      • iface enp0s3 inet dhcp
        • dhcp 由dhcp自动分配ip地址
      • up/pre-up /sbin/ethtool -s enp0s3 speed 1000 duplex full 网卡启动前运行此条命令
    • 静态IP地址

      iface enp0s3 inet static
      	address 192.168.1.1		# 指定ip地址
      	netmask 255.255.255.0	# 指定子网掩码
      	gateway 192.168.1.254	# 指定网关
      
      • 更多配置
        • broadcast 192.168.1.255 指定广播地址
        • dns-nameservers 192.168.1.1 8.8.8.8 设置DNS服务器,一般为容错指定多个
        • dns-search example.com sales.example.com dev.example.com 如果主机属于某个dns域,指定域名,从这个域名搜索相应的主机记录
        • up/pre-up route add -net 172.16.0.1/24 gw 192.168.1.1 网卡启用前执行此条命令
        • down route del -net 172.16.0.1/24 网卡禁用之前执行此命令,删除172.16.0.1/24的路由
        • mtu 1500 最大包的长度(字节),最大传输单元
        • hwaddress 00:11:22:33:44:55 硬件地址,网卡的MAC地址

5.2.4 网络基本设置 {#524-网络基本设置}

  • 设置ip
    • sudo ifconfig enp0s3 10.0.0.100 netmask 255.255.255.0 设置enp0s3网卡的ip地址和子网掩码,临时(重启后就不在是这个了)
    • sudo ifconfig enp0s3 10.0.0.100/24 设置enp0s3网卡的ip地址和子网掩码,255.255.255.0每个255转成二进制就是8个1,有三个255就有24个1,所以这里用/24表示子网掩码,和上面的命令是一个意思,临时
  • 设置网关 {#add-net}
    • sudo route add default gw 10.0.0.1 enp0s3 设置网关
    • sudo route add -net 0.0.0.0 netmask 0.0.0.0 gw 10.0.0.2 设置网段路由,如果都是0.0.0.0就和上一条的命令(default)相同意思,可以更改0.0.0.0表示访问某一网段指向另外一个网关
    • sudo route add -host 2.2.2.2 gw 1.1.1.1 主机路由,去往某个具体的主机使用哪个网关
  • 配置网卡
    • sudo vim /etc/resolv.conf DNS设置(软链接)
    • sudo ip addr flush enp0s3 清楚网卡配置
    • sudo ifconfig enp0s3 down 禁用网卡
    • sudo ifconfig enp0s3 up 启用网卡
    • sudo systemctrl restart networking.service 重启网络服务
  • 查看路由
    • route -n
    • netstat -nr

5.3 DNS配置 {#53-dns配置}

  • 主机名解析

    • sudo vim /etc/hosts ip和域名的解析关系,优先级高于resolv.conf(可修改优先级),如果有访问的域名则访问对应的ip而不会再去请求域名服务器
      • 127.0.0.1 localhost
      • 127.0.1.1 ubuntu-server
      • 10.0.0.11 server1 server1.example.com
  • 修改解析顺序

    • sudo vim /etc/nsswitch.conf 名称解析顺序配置文件
      • files 指的是/etc/hosts文件
      • Resolve 完整名:systemd-resolved.service,是一个服务,用来解析 本机名、localhost、缓存
      • [!UNAVAIL=return] 是一个正则表达式,在本地缓存中寻找,结果即权威,UNAVAIL表示服务不可用,前面加 ! 表示不是服务不可用的时候,return表示返回缓存的结果,这个正则还有其他的写法,比如[NOTFOUND=return]
      • dns DNS服务器
      • mdns4_minimal Multicast DNS(多播)

5.4 网桥配置 {#54-网桥配置}

5.4.1 介绍 {#541-介绍}

  • 将多个以太网段以上层协议透明的方式连接在一起
    • 二层转发,对三层协议透明
    • 启用防火墙可对流量过滤
    • 桥接宿主机与虚拟网络,使虚拟机访问外部网络
    • 桥接有线网与无线网
    • 链路冗余容错(需启用STP)
    • 通过网桥管理工具实现bridge-utils

5.4.2 搭建网桥 {#542-搭建网桥}

  • 安装网桥管理包

    • sudo apt install bridge-utils
  • 查看网桥

    • sudo brctl show 查看网桥的运行状态
    • sudo brctl showmacs br0 查看网桥侦听到的mac地址
    • sudo brctl showstp br0 查看参与的生成树计算的情况
  • 临时配置

    • sudo brctl addbr br0 添加一个网桥
    • sudo brctl addif br0 enp0s3 enp0s8 将enp0s3 enp0s8加入到br0网桥中去
    • sudo ifconfig enp0s3 0.0.0.0 up 清除enp0s3的ip
    • sudo ifconfig enp0s8 0.0.0.0 up 清除enp0s8的ip
    • sudo ifconfig br0 192.168.1.112/24 up 手动设置网桥网卡的ip
    • sudo dhclient br0 通过dhcp服务器为网桥网卡自动分配ip
    • sudo route add default gw 192.168.1.1 指定网关
  • 持久配置

    • sudo vim /etc/network/interfaces
      • auto enp0s3
      • iface enp0s3 inet manual
      • auto enp0s8
      • iface enp0s8 inet manual
      • auto br0
      • iface br0 inet static
      • address 192.168.1.112
      • netmask 255.255.255.0
      • gateway 192.168.1.1
      • bridge_ports enp0s3 enp0s8 将enp0s3 enp0s8加入到网桥中
      • bridge_stp off 关闭生成树协议

5.5 网卡绑定 {#55-网卡绑定}

5.5.1 简介 {#551-简介}

  • Bonding==Port Trunking==Linux aggregation==Teaming 这几个称呼意思相同

  • 将多个物理网卡组合成一个逻辑网卡

    • 高可用、负载均衡、高吞吐量

5.5.2 启用网卡绑定 {#552-启用网卡绑定}

  • sudo echo bonding >> /etc/modules 添加内核支持
    • 在这个配置文件中加入一行,内容为 bonding ,这样以后启动系统会自动加载
  • sudo modprobe bonding 手动加载内核
  • sudo systemctl stop networking 重启网络服务
  • sudo vim /etc/network/interfaces 编辑配置文件来配置网卡绑定

5.5.4 Mode介绍 {#554-mode介绍}

  • Mode 0:round-robin
    • 网络流量(数据包)顺序平均分配给Bond中所有的物理网卡
    • 高可用、负载均衡
  • Mode 1:active-backup
    • Bond中只有一个网卡Active,其他网卡全部Stanby
    • 对外只有一个网卡MAC地址可见
    • 高可用
  • Mode 2:balance-XOR
    • Bond网卡会使用唯一不变的MAC地址,加入到Bond中的物理网卡都会使用Bond的MAC地址,所以对外的MAC地址是不变的
    • 根据源和目的的MAC/IP/Port进行计算,确定从哪个网卡发出**(性能优于Mode 0)**
      • 根据源和目标的MAC/IP/Port进行计算,异或计算/哈希计算等,除以3(Bond中物理网卡的个数,这里假设是3块)余数为0由第一块网卡发,余数为1由第二块网卡发,余数为2由第三块网卡发
      • 只要目标的MAC/IP/Port不变,则计算的结果都是相同,余数也就永远相同,那么如果第一次是第1块网卡和目标通信的,则后面所有的通信都会使用这块网卡
      • MAC 二层、IP 三层 、Port 四层,算法可以由某一层或者多层结合,还是挺复杂的,有7、8种
    • 高可用、负载均衡
  • Mode 3:broadcast
    • 发包广播给Bond中所有的网卡,提供最短的故障恢复时间,应用连接不中断
    • 高可用
  • Mode 4:802.3ad(Dynamic link aggregation)
    • 链路聚合 LACP组内的网卡使用相同速率、双工设置
    • 要求:计算机安装ethtool;交换机支持IEEE 802.3ad标准,并进行额外配置
    • 高可用、负载均衡
  • Mode 5:balance-tlb(Adaptive transmit load balancing)
    • 隧道绑定不需要上联交换机额外配置,根据网卡负载出站负载均衡
    • 高可用、负载均衡
  • Mode 6:balance-tlb(Adaptive transmit load balancing)
    • Mode 5 + banace-rlb(入站流量负载均衡)
      • Bond驱动拦截本机的ARP响应包,使用不同网卡硬件MAC替换源MAC
      • 不同的对端使用不同的服务器MAC地址,实现入站负载均衡
    • 不需要上联交换机额外配置
  • 查看bond端口信息
    • cat /proc/net/bonding/bond0 bond0为名字

5.5.5 Mode配置 {#555-mode配置}

  • Mode 1 配置

    • 主备,一个为主,其他为备用,当主的发生故障,备用的顶上

    • auto enp0s3 其他网卡配置相同

    • iface enp0s3 inet manual 设置成manual

    • bond-master bond0 被属于bond0

    • bond-primary 设置成主,只有Active网卡需要

    • auto bond0

    • iface bond0 inet dhcp 也可配置静态地址

    • bond0-mode active-backup 也可使用 mode 编号

    • bond-millmon 100 故障检测间隔,单位 毫秒

    • bond-slaves none enp0s3配置中已经声明bond-master和primary,所以写none

    # This file describes the network interfaces available on your system
    # and how to activate them. For more information, see interfaces(5).
    
    source /etc/network/interfaces.d/*
    
    # The loopback network interface
    auto lo
    iface lo inet loopback
    
    # The primary network interface
    auto enp0s3							
    iface enp0s3 inet manual				# 设置成manual
    bond-master bond0                       # 表示属于bond0
    bond-primary enp0s3                     # 表示是主网卡
    
    auto enp0s8
    iface enp0s8 inet manual				# 设置成manual
    bond-master bond0						# 表示属于bond0
    
    auto bond0
    iface bond0 inet dhcp					# 通过dhcp获取ip,也可设置成static,手动指定ip等
    bond-mode 1								# 表示是mode1模式,也可以写成 active-backup
    bond-miimon 100                         # 表示每隔100毫秒检测一次
    bond-slaves none						# 后面加上属于的网卡,一般写none,然后在被属于的网										  卡后面添加bond-master
    

  • Mode 4 配置

    • auto enp0s3 其他网卡配置相同

    • iface enp0s3 inet manual 设置成manual

    • bond-master bond0 被属于bond0

    • auto bond0

    • iface bond0 inet dhcp 也可配置静态地址

    • bond0-mode 4 设置mode类型

    • bond-millmon 100 故障检测间隔,单位 毫秒

    • bond-lacp-rate 1 每1秒发送LACPDU(默认0,即30秒)

    • bond-slaves enp0s3 enp0s8

    # This file describes the network interfaces available on your system
    # and how to activate them. For more information, see interfaces(5).
    
    source /etc/network/interfaces.d/*
    
    # The loopback network interface
    auto lo
    iface lo inet loopback
    
    # The primary network interface
    auto enp0s3							
    iface enp0s3 inet manual				# 设置成manual
    bond-master bond0                       # 表示属于bond0
    
    auto enp0s8
    iface enp0s8 inet manual				# 设置成manual
    bond-master bond0						# 表示属于bond0
    
    auto bond0
    iface bond0 inet dhcp    			# 也可配置静态地址
    bond0-mode 4    					# 设置mode类型
    bond-millmon 100    				# 故障检测间隔,单位 毫秒
    bond-lacp-rate 1    				# 每1秒发送LACPDU(默认0,即30秒)
    bond-slaves enp0s3 enp0s8    		# 设置属于的物理网卡
    

5.6 DHCP服务 {#56-dhcp服务}

5.6.1 简介 {#561-简介}

  • Dynamic Host Configuration Protocol
    • 透明的配置网络参数
    • IP/掩码、网关、DNS、域名、主机名、时间服务器、打印服务器等(200多种)
    • 通过地址租约循环使用IP地址
    • 使用UDP 67 / 68 端口,标准情况下服务器使用67端口,客户端使用68端口,客户端有可能会使用其他端口,但是服务器永远是67端口

5.6.2 安装 {#562-安装}

  • sudo apt install isc-dhcp-server

5.6.3 配置 {#563-配置}

  1. sudo vim /etc/default/isc-dhcp-server 指定启动DHCP服务的网卡

    • INTERFACESv4="ens33" 在双引号里面添加想启用dhcp的网卡,多个用空格隔开

  2. sudo vim /etc/dhcp/dhcpd.conf 主配置文件(指定址池和选项)

    • 以option开头的是针对某个地址池的配置,而不以option开头的是针对DHCP服务器的配置
    • 当客户端获取DHCP服务器分配的IP后,当租约时间过了一半的时候(假设10分钟)也就是5分钟的时候,会向DHCP服务器发起请求重新刷新时间为10分钟,当累计使用时长到达最大租约时间的时候,就要重新discover,让DHCP服务器重新分配给一个IP;如果在刷新时间的过程中DHCP发生了故障,那么客户端会再过剩余租期时间的一半(7分30秒时)再次发起请求刷新时间,如果未得到响应就会再过剩余租期时间的一半在此发起请求(8分45秒),直至租约到期,重新discover,等待DHCP分配IP,如果DHCP服务器还没有恢复,那么客户端就没有IP了
    • DHCP服务器有个记录,使用客户端的MAC地址记录上次分配的IP,如果这一次不出意外的话,还是会给那个客户端分配上次分配的IP
    option domain-name-servers 10.1.8.1,8.8.4.4;    # 配置域名
    default-lease-time 600;							# 租约时间
    max-lease-time 7200;							# 最大租约时间
    ddns-update-style none;
    authoritative;									# 如果dhcp是正确配置且是权威的,则开启此项
    
    subnet 10.1.8.0 netmask 255.255.255.0 {			# 一个地址池的配置,设定了网段和子网掩码
      range 10.1.8.100 10.1.8.200;					# 配置起始和结束的ip
      option routers 10.1.8.1;						# 配置网关,option只针对这个池有效
      option domain-name-servers 10.1.8.1,202.106.0.20;	# 配置DNS服务器
      option domain-name "lab.com";					# 给分配的计算机指定一个统一的域名
      option ntp-servers 10.1.8.1;					# 配置时间服务器
    }
    

  3. DHCP地址保留

    • 就是将每个地址分配个特定的计算机
    host name {									# 主机保留地址
        hardware ethernet 00:11:22:33:44:55;	# 指定网卡MAC地址
        fixed-address 192.168.1.11;				# 子网内地址,可为range外地址(建议使用)
    }
    

5.6.4 日志与状态查询 {#564-日志与状态查询}

  • cat /var/lib/dhcp/dhcpd.leases 服务器地址租约结果
  • tail -f /var/log/syslog 服务器日志
  • sudo systemctl status isc-dhcp-server 服务器运行状态
  • cat /var/lib/dhcp/dhclient.ens33.leases 查看客户端获得地址

5.7 NTP服务 {#57-ntp服务}

5.7.1 简介 {#571-简介}

  • NTP服务器【Network Time Protocol(NTP)】是用来使计算机时间同步化的一种协议
  • 我们每天都在用的网络时间协议
  • 计时方法
    • 太阳照影、滴水、烧香、机械、电子、石英、原子时钟(铯133)
    • Drift表示计时器时间与真实时间之间的偏移量
    • 基于铯133的原子时钟每3亿年误差为1秒
  • 时间标准
    • GMT:格林威治标准时间
    • UTC:世界协调时间
    • CST:China Standard Time UT+8:00
  • 跨时区沟通呼唤统一的时间定义
  • 计算机技术对时间非常敏感
    • IPSec、AD、SSL
    • 日志审计
    • 电子元件器相互干扰加大时间偏移
  • 如何保证时间准确
    • 不停地同步时间
    • 永远无法精确同步(网络通信延时影响时间同步精度)

5.7.2 NTP协议 {#572-ntp协议}

  • NTP协议的分层架构 {#NTP_5.7.2}
    • 从核心向外0-16层stratum(地壳)
    • 0代表时间源
    • 1-15代表逐级同步的时间服务器(越接近0时间越精确,真实环境一般不超过5层)
    • 16表示尚未同步(还不能作为时间同步源)
    • 客户端服务器默认全部使用udp123端口通信
  • 每个移动设备都运行NTP协议
    • 硬件时钟:RTC(主板电池供电)
    • 系统时钟:Local time

5.7.3 NTP客户端 {#573-ntp客户端}

  • NTP客户端

    • 客户端程序从时间服务器同步时间
    • 系统启动时自动同步时间
    • 网卡激活时自动同步时间
    • 手动同步时间
  • 客户端命令

    • timedatectl 查看客户端时间

    • 新版系统使用timesyncd客户端同步时间

      • 向 ntp.ubuntu.com 请求当前时间
    • timedatectl list-timezones 列出所有时区

    • timedatectl set-timezone "Asia/Shanghai" 设置时区

    • timedatectl settime "2000-1-1 01:02:03" 设置时间

    • timedatectl set-ntp true/false 开启/关闭 网络时间同步服务

    • sudo systemctl status systemd-timesyncd.service 查看时间同步服务运行状态

    • sudo hwclock -w 将系统时间写入到硬件时间

    • sudo hwclock -s 将硬件时间写入到系统时间

    • hwclock --set --date='2000-1-1 01:02:03' 设置硬件时间

      • 设置的时间认为是当前时区时间,系统会计算成UTC时间,比如当前在东八区,那么真实设置的时间会是设置的时间减8小时
  • 早期版本客户端软件 ntpdate

    • 新版系统已经默认不安装ntpdate
    • sudo apt install ntpdate 安装ntpdate
    • sudo ntpdate ntp.ubuntu.com 向指定服务器发起时间同步请求
    • sudo ntpdate -d 1.1.1.1 -d 显示时间同步详细过程
    • sudo ntpdate -q 1.1.1.1 -q 只查询时间,并不更新本地时间
    • sudo ntpdate -u 1.1.1.1 -u 随机源端口(多个ntp客户端都使用123端口会发生冲突)
    • 一旦安装ntpdate / ntp ,timedatectrl 将被禁用

5.7.4 NTP服务器 {#574-ntp服务器}

  • ntpd:客户端 + 服务器

    • sudo apt install ntp 安装ntp服务

    • sudo systemctl status ntp 查询服务状态

    • sudo systemctl restart ntp 重启服务

    • sudo vim /etc/ntp.conf 配置文件

      • server 1.1.1.1 指定同步的服务器
      • fudge 127.127.1.1 stratum 10 使用本机时钟作为备用时间源,stratum 10表示ntp协议的层级

  • 新版系统使用timesyncd替换ntpd的客户端功能

    • 老版的系统ntpd既作为客户端也能作为服务端
    • /etc/systemd/timesyncd.conf 配置文件
  • ntpq -p

    • remote 本机正在连接的上级时间服务器
    • refid 上级服务器的上级时间服务器
    • st 服务器stratum层级
    • t 协议类型:unicast(单播),broadcast(广播),multicast(多播),anycast(任意播)
    • when 上一次查询服务器已过去的时间(秒)
    • poll 查询服务器的时间间隔(64=2^6)
    • reach 最近8次查询结果成功则为377(8进制数),如果为377则可以开始时间服务,否则不能对外提供时间服务
    • delay 请求和响应之间的时间差(毫秒)
    • offset 本地时间与服务器的时间偏移
    • jitter 与服务器的网络延时,此值应该小于100
    • 每行第一个字符
      • 空表示无效主机
      • x 表示已不再使用
        • 表示已不再使用
      • 表示状态良好但未使用

        • 表示良好且优先使用
      • * 表示主同步主机

5.7.5 其他命令 {#575-其他命令}

  • date 显示当前系统时间
  • sudo date --set 1998-10-23 设置日期(需要先禁用时间同步)
  • sudo date --set 21:08:30 设置时间
  • cat /etc/timezone 查看当前时区,也可以更改

第 6 章 帐号管理 {#第-6-章-帐号管理}

6.1 用户账号管理基础 {#61-用户账号管理基础}

6.1.1 用户账号 {#611-用户账号}

  • 用户账号管理
    • 为新员工创建账号
    • 修改账号密码策略
    • 禁用休假员工账号
    • 删除离职员工账号
    • 设置账号访问权限
  • 每个人保管自己的密码
    • 不要讲密码泄露给任何人
    • 保证密码复杂度
    • 不要将密码写在纸条上贴在显示器上
  • Root账号
    • 能做任何事情(甚至删除操作系统自身)
    • 大部分Linux发行版安装时要求设置root账号密码
    • Ubuntu默认禁用Root账号
      • 可sudo或临时切换为root账号
      • 可手动启用root账号
    • 平时以普通员工账号管理计算机
    • rm -rf /
  • 安装过程中创建管理员个人账号
    • 作为日常管理使用

6.1.2 创建账号 {#612-创建账号}

  • useradd -d /home/user01 -m user01

    • -d 指定账号主目录的路径(复制于/etc/skel)
      • 路径中的目录要首先创建好,比如指定为/H/user/user01,那么H和user目录要先创建好
    • -m 创建账号的同时创建主目录(默认首次登录时创建主目录),强烈建议在创建账号的时候加上这个参数
      • 在ubuntu中如果创建账号的时候没有同时生成主目录,则/etc/passwd中默认让其使用的是/bin/sh这个shell
    • -c 全名(描述)
    • -e 账号在YYYY-MM-DD时过期
    • -N 不创建同名组账号
    • -g 指定主组(必须已经存在),不会创建和账号同名的组
    • -G 指定主组,但是还是会创建和账号同名的组
    • -s 指定用户登入后所使用的shell,默认是/bin/bash,若写 -s /bin/false则表示禁用shell登录权限
    • -U 创建与用户同名的组
    • 账号名最长32个字符
    • 用户主目录拷贝自/etc/skel

6.1.3 创建账号(向导模式、批量添加) {#613-创建账号向导模式批量添加}

  • adduser user01

    • 基于useradd的perl脚本
    • 并非所有Linux发行版中都包含
    • 向导方式运行(不需要记忆命令参数)
    • /usr/sbin/adduser
  • 批量添加账号

    • sudo newusers users.txt

      • users.txt按passwd文件格式来写,UID和GID可不用写,例如
      user13:pass13:::lisi:/home/user13:/bin/bash
      user14:pass14:::wangwu:/home/user14:/bin/bash
      

6.1.4 管理账号和密码 {#614-管理账号和密码}

  • passwd user01 设置user01账号的密码
    • -l 锁定账号的密码!
    • -u 解锁账号
    • -d 删除密码(不需要密码就能登录)
    • -n / -x 密码 最小/最大 使用期限
    • -w 密码快过期时提前多少天前发警告
    • -i 密码过期多少天后锁定账号
    • -e 密码立刻过期(下次登录必须更改密码)
    • -S 查看账号的密码状态(L锁定、P活动)
      • passwd -a -S/passwd -Sa 查看所有账号的状态

6.1.5 删除账号 {#615-删除账号}

  • sudo userdel user01 删除user01账号
    • 未同时删除用户主目录
    • 未进行文件备份
  • sudo rm -rf /home/user01 删除用户主目录
  • sudo userdel -r dscully 删除账号同时删除其主目录和邮件

6.1.6 切换账号 {#616-切换账号}

  • 切换到 root 账号
    • su 需要输入root密码
    • sudo su 输入当前账号密码(当前账号属于sudo组)
    • sudo -i 输入当前账号密码(当前账号属于sudo组)
    • sudo -s 输入当前账号密码(当前账号属于sudo组)
  • 切换到其他账号
    • su user01 切换到user01账号
    • sudo su user01 切换到user01账号

6.2 账号数据库 {#62-账号数据库}

6.2.1 /etc/passwd {#621-etcpasswd}

  • 用户名:密码:UID:GID:全名,房间号,z工作电话,家庭电话,others:主目录:shell
    • 密码都是 x ,是一个占位符,真正密码和密码相关的信息存在/etc/shadow文件中
  • 保存了系统中所有的账号信息,一行代表一个账号

6.2.2 /etc/shadow {#622-etcshadow}

  • 用户名:密码
    • 密码为 "!"、"*****"的账号不能直接登录系统(其他账号登陆后可切换为)
    • !密码: 表示密码被锁定
  • :上次修改日期 (第二个冒号)
    • 上次修改日期是自1970-01-01起到修改密码的天数
    • 上次修改日期如果是0表示用户下次登录时需要修改密码,空表示关闭密码过期功能
  • :密码最少使用期:密码最长使用期 (第3,4个冒号)
    • 后值小于前值时,用户无法更改密码
  • :密码快过期时提前几天提醒 (第5个冒号)
    • 账号过期则不能登录系统,而密码过期还能登录系统但是系统会一直提醒密码已经过期,可以设置当密码过期时把账号也设置为过期,也就是下一个冒号后的设置
  • :密码过期多少天后账号会被锁定 (第6个冒号)
    • 账号过期用户不能登录,密码过期看此设置的数字(天)来锁定账号
  • :账号过期日 (第7个冒号)
    • 距1970-1-1的天数
  • :保留(第8个冒号)
user02:$6$RxJawPKg$hR7g4WxyuflS21b/WHzEUChFmKMYAUjElQK8nH0WmF3.4MIaq14ZrTCZZSgdZk.yn3tKLTewdKkXIQOWuro26/:0:0:99999:7:::

每一行给一个特殊帐户定义密码信息,每个字段用 : 隔开。
字段 1 定义与这个 shadow 条目相关联的特殊用户帐户。
字段 2 包含一个加密的密码。
字段 3 自 1/1/1970 起,密码被修改的天数
字段 4 密码将被允许修改之前的天数(0 表示"可在任何时间修改")
字段 5 系统将强制用户修改为新密码之前的天数(1 表示"永远都不能修改")
字段 6 密码过期之前,用户将被警告过期的天数(-1 表示"没有警告")
字段 7 密码过期之后,系统自动禁用帐户的天数(-1 表示"永远不会禁用")
字段 8 该帐户被禁用的天数(-1 表示"该帐户被启用")
字段 9 保留供将来使用

6.3 组账号管理 {#63-组账号管理}

6.3.1 什么是组? {#631-什么是组}

  • 将用户账号分组管理和指派权限
  • 用户创建时同时生成同名的组账号
  • 每个文件有唯一的所属账号和所属组(属主、属组)
    • 每个用户可以同属于多个组,但只有一个主组

6.3.2 查看组 {#632-查看组}

  • groups 查看当前用户所属的组
  • cat /etc/group 查看系统中所有的组
    • 组名:密码(通常不使用):GID:逗号分隔的成员为用户账号

6.3.3 组管理 {#633-组管理}

  • sudo groupadd gname 添加组gname
  • sudo groupdel gnmae 删除组gname
  • sudo gpasswd -a user01 gname 将user01加入额外组gname
  • sudo usermod -aG gnmae user01 将user01加入额外组gname
    • -a 附加(否则替换)
  • sudo usermod -g gname user01 修改用户user01主组为gname
  • sudo usermod -d /home/user1 user01 -m 将主目录内容移动到新位置
    • -d 指定新的主目录
    • -m 表示移动主目录
    • 原有的主目录会删除
  • sudo usermod -l user02 user01 将用户user01修改为user02
  • sudo gpasswd -d uname gname 将用户uname从组gname中删除

6.4 密码策略 {#64-密码策略}

  • Pluggable Authentication Mode(PAM)
    • sudo apt install libpam-cracklib 安装libpam-cracklib
    • sudo vim /etc/pam.d/common-passwd
      • passwd required pam_pwhistory.so remember=9 use_authok(设置历史密码9次之内不能相同)

6.5 文件权限和属主属组 {#65-文件权限和属主属组}

6.5.1 文件权限 {#651-文件权限}

  • 每个文件和文件夹拥有唯一的属主和属组

    • ls -l
  • 权限类型

    • r、w、x 读、写、执行
    • u、g、o 属主、属组、其他

    | 权限 | 文件 | 文件夹 | |----|------------|----------------| | r | 读取文件内容、拷贝 | 列出目录内容 | | w | 更改文件内容 | 创建、删除文件及文件夹 | | x | 作为应用程序执行文件 | cd进入、读取文件属性和权限 |

6.5.2 设置权限 {#652-设置权限}

  • 属主和 root 可以修改权限
    • chmod u+rw a.txt 将a.txt文件的所有者权限加上rw
    • chmod g-w a.txt 将a.txt文件的权限减去w
    • chmod 664 a.txt 将a.txt的权限修改为664(r 4,w 2,x 1)
    • chmod 770 -R path/ 将path目录及其下面的文件和目录都改为770
  • 权限与搜索
    • sudo find /path/dir/ -type f -perm 644 -user luo -group luo -exec chmod 664 {} ; 搜索/path/dir/路径下,是文件类型,权限为644,所有者为luo账号,所属组为luo,搜到的结果执行chmod 644命令,{}为搜到的结果,";"是exec后面必须加的
    • sudo find /path/dir/ -type d -perm 755 -user luo -exec ls -l {} ; 搜索/path/dir/路径下,是目录类型,权限为755,所有者为luo账号,搜到的结果执行ls -l命令,{}为搜到的结果,";"是exec后面必须加的
    • sudo find /home -nouser -exec rm -rf {} ; 在home目录下查找无有效属主对象(账号已删除),然后执行rm -rf命令删除这些文件或目录

6.5.3 修改属主与属组 {#653-修改属主与属组}

  • sudo chown luo a.txt 将a.txt文件的所有者修改为luo账号
  • sudo chown -R luo /path 将path目录及其下面所有的文件和目录的所有者修改为luo账号
  • sudo chown luo:luo a.txt 将a.txt文件的所有者和所属组修改为luo账号和luo组
  • sudo chgrp users a.txt 将a.txt文件的所属组改为users组

6.5.4 特殊权限 {#654-特殊权限}

  • Setuid(4)
    • 主要针对可执行程序
    • 任何用户指向程序时使用所有者的权限
    • chmod u+s a.sh / chmod 4777 a.sh(在前面多加了一位4表示Setuid)
  • Setgid(2)
    • 主要针对可执行程序和目录
    • 任何用户指向程序时使用所有组的权限
    • 应用于目录时可实现共享访问的效果(新建文件的属组继承目录属组)
    • chmod g+s /path / chmod 2777 a.sh(在前面多加了一位2表示Setgid)
  • sticky bit(1)
    • 针对目录的受限删除位(root、所有者可以删)
    • /temp目录即为典型例子
    • chmod 0+t /path / chmod 1777 a.sh(在前面多加了一位1表示sticky)

6.5.5 权限掩码 {#655-权限掩码}

  • 决定文件和目录的默认权限

    • 文件默认权限:664-掩码
    • 目录默认权限:775-掩码
  • umask 显示当前掩码

    • 002 用户名与组名相同、UID与GID相同
  • umask 027 将掩码临时修改为027,重启后失效

    • 文件的最大权限是666,目录的最大权限是777,用他们的最大权限减去掩码即为默认权限,比如掩码为027,这文件的默认权限是640,目录的默认权限是750
  • sudo vim /etc/login.defs 修改之后,对umask的修改永久生效

    • UMASK 022 修改UMASK

    • USERGROUPS_ENAB yes 如果设置成了yes会将掩码的属主覆盖属组,比如正常是022,如果设置了yes,掩码将是002

    • 如果想要UMASK设置为什么就为什么,那么可以将 USERGROUPS_ENAB 设置为no,或者将账号的UID和GID修改为不同

第 7 章 远程管理 {#第-7-章-远程管理}

7.1 远程访问方式 {#71-远程访问方式}

  • 服务器大多部署在专门的机房环境
    • 电磁、噪声、氧气、温湿度等都不适合人类长期活动
    • 避免闲杂人等接触业务服务器
  • 远程管理
    • 不同的操作系统都支持远程管理技术
    • 命令行远程管理工具
    • 图形化远程管理工具

7.2 Telnet {#72-telnet}

7.2.1 介绍 {#721-介绍}

  • 古老的命令行远程管理工具
    • 不安全(明文传输一切数据)
    • 应尽量避免使用(适用于不支持SSH的环境)
    • 客户端程序包含在所有系统的默认安装中
    • 服务端口默认TCP 23

7.2.2 客户端 {#722-客户端}

  • telnet 192.168.2.207 连接目标,默认23端口

  • telnet www.baidu.com 80

    • telnet连接baidu的80端口,连接上之后就可以输入http的请求信息来得到相应的返回信息
  • Telnet可以连接任何域名的任何端口

7.2.3 服务器安装 {#723-服务器安装}

  • sudo apt install telnetd 安装telnet服务端程序

  • sudo vim /etc/issue.net 避免泄露版本信息,可以改成本服务器属于xxx公司所有,如果你不是本公司网络管理员请不要尝试连接,否则一切法律责任由你自行承担......

  • 查看服务状态

    • systemctl status inetd.service

7.3 SSH {#73-ssh}

7.3.1 SSH服务器安装 {#731-ssh服务器安装}

  • sudo apt install openssh-server openssh是一个服务套件,不仅会安装ssh的服务端程序,还会安装一大堆ssh相关的工具
    • sftp <--> ftp openssh会安装这个sftp工具,安全的文件传输 {#sftp}
      • ftp 明文传输
      • sftp 相当于将ssh和ftp结合,ssh将通信的双方建立一个安全的隧道是加密的,在这个隧道中传输的数据都是加密的,然后将ftp数据通过这个隧道传输
    • scp <--> rcp openssh会安装这个scp工具,拷贝的工具 {#scp}
      • rcp 明文传输
      • scp 相当于将ssh和rcp结合,ssh将通信的双方建立一个安全的隧道是加密的,在这个隧道中传输的数据都是加密的,然后将rcp数据通过这个隧道传输
    • 服务端端口默认TCP 22
    • SSH1、SSH2两个版本(版本2更安全)
    • sudo vim /etc/ssh/sshd_config ssh服务的配置文件
  • 查看服务状态
    • systemctl status sshd.service

7.3.2 配置修改 {#732-配置修改}

  • sudo vim /etc/ssh/sshd_config ssh服务的配置文件
Banner /etc/issue.net        # 登录前提示信息
Port 2222                    # 工作端口
PubkeyAuthentication yes     # 缘续公钥登录,ssh除了可以用账号密码登录外还可以用公私钥来进行登录
ListenAddress 12.34.56.78    # 侦听地址,比如服务器有两块网卡,现在只能让用户通过第一块网卡来进行ssh连接,那么后面的地址就写第一块网卡的IP地址
PermitRootLogin no           # 是否允许root账号来通过SSH登录
							 # no表示完全禁用
							 # prohibit-password表示禁止通过账号密码登录,但是可以通过公钥的方式登录
Protocol 2                   # 只允许SSH 2协议来连接
AllowUsers user1 user2       # 只允许user1和user2账号通过SSH连接
DenyUsers user3              # 进制user3账号通过SSH连接
AllowGroups sshusers         # 只允许sshusers组里面的账号可以通过SSH连接
PasswordAuthentication no    # 禁止使用密码登录

SSH配置详解

7.3.3 SSH工具 {#733-ssh工具}

  • scp工具
    • SSH、SCP的组合
    • scp a.txt 192.168.2.207: 拷贝一个文件到目标机器上
      • 默认本地账号与远程系统账号同名,默认目标主目录
    • scp a.txt study@192.168.2.207:/tmp/b.txt 指定用户名、目标路径
      • 将本机的a.txt通过192.168.2.207机器上的study账号拷贝到/tmp/b.txt上
    • scp -rv dir/ study@192.168.2.207: 拷贝一个目录
      • r 递归拷贝
      • v 显示详细的进度
    • scp study@192.168.2.207:/tmp/b.txt . 下载文件到当前目录
  • sftp工具
    • SSH、FTP的组合
    • sftp study@192.168.2.207
      • sftp> help、ls、cd、get(下载)、wget、put(上传)、mput、quit

7.3.4 SSH客户端连接 {#734-ssh客户端连接}

  • ssh study@192.168.2.207

  • ssh -l study 192.168.2.207

  • 客户端配置文件

    • ~/.ssh/config 手动新建config文件
    host fileserver               # 这一组名称,随意
    	Hostname 192.168.2.207
    	Port 22
    	User zhangsan
    Host mailserver               # 这一组名称,随意
    	Hostname mail.lab.com
    	Port 2222
    	User lisi
    # 然后就可以使用 ssh fileserver 这条命令连接192.168.2.207:22机器上的zhangsan账号,就省去了输入IP、端口、账号等
    

  • ssh连接远程服务器自动断开解决

    • ssh连接长时间不操作自动断开

    • 修改服务器端参数

      # 如果你用多台本地机器连接服务器,可以考虑把服务器端的配置作修改路径是:/etc/ssh/sshd_config,在其中添加一行内容,意思是向客户端每60秒发一次保持连接的信号
      ClientAliveInterval  60
      
      # 如果仍要设置断开时间,还有一个参数可以添加
      ClientAliveCountMax  60	# 意思是如果客户端60次未响应就断开连接,依据你期望的时间来设定
      
    • 修改本地参数

      # 也可以让客户端向服务器发送保持连接信号,路径是/etc/ssh/ssh_config
      
      # 在其中类似的添加相应的参数也行
      ServerAliveInterval  60
      ServerAliveCountMax  60
      
    • 使用ssh登录时也可设置参数

      # 在连接前使用-o 可以设置相应的参数
      ssh -o ServerAliveInterval=30 root@192.168.1.1
      

7.3.5 SSH公钥登录 {#735-ssh公钥登录}

  • 非对称算法(公钥算法)
    • 公钥、私钥
    • 一次数学运算会生成两个值,一个是公钥,一个是私钥,无所谓哪个是公钥哪个是私钥,用公钥加密的只能用对应的私钥解密,用私钥加密只能用对应的公钥解密
    • 公钥是拿出去给别人用的,私钥是要严格保密的
  • 生成密钥对
    • ssh-keygen -t rsa -b 4096
      • 使用rsa非对称加密算法,指定密钥长度为4096
      • ~/.ssh/id_rsa 私钥位置
      • ~/.ssh/id_rsa.pub 公钥位置
    • ssh-keygen -t rsa -b 4096 -f id_mail 命名密钥对,生成的密钥对叫id_mail用来登录邮件服务器,生成id_ftp用来登录ftp服务器等
    • ssh-keygen -p -f ~/.ssh/id_rsa 修改私钥密码文,也可以设置为空(不建议)
      • p 修改密码
      • f 指定修改的目标
  • 上传拷贝公钥
    • ssh-copy-id study@192.168.2.207 拷贝公钥到目标机器上(本机只有一个公钥时)
    • ssh-copy-id -i id_rsa.pub study@192.168.2.207 拷贝指定的公钥到目标机器上
    • 拷贝后目标机器会生成~/.ssh/authprized_keys文件,内容和生成的公钥内容一样
    • 上传完公钥后,再次用ssh连接时就不需要输入账号密码了,输入的密码是私钥的密码,如果把私钥的密码设置为空那么就直接连接了,什么密码都不用输入了,当然不建议这么做
  • 密钥文件权限
    • chmod 400 ~/.ssh/id_rsa 客户端私钥文件权限
    • chmod 600 ~/.ssh/authprized_keys 服务器授权密钥文件权限

7.3.6 SSH其他应用 {#736-ssh其他应用}

  • 登录

    • ssh study@192.168.2.207 登录系统

    • ssh -i ~/.ssh/id_mail study@192.168.2.207 -p 2222 ping 192.168.2.1

      • i 指定一个私钥文件为这次通信加解密,如果只生成一个密钥对就不需要在后面指定秘钥文件,默认就会使用那一个
      • p 指定端口,如果目标使用非标准端口
      • 这条命令前部分是登录目标机器然后自动执行ping命令,ping命令执行完了就结束了本次通信
    • tar -cj dir/ | pv | cstream -t 100k | ssh study@192.168.2.207 'tar -xj'

      • tar -cj 生成tar包并压缩
      • pv 显示传输过程中对带宽的占用情况
      • cstream -t 1M 限速为1M
      • tar -xj 解压上传的tar包
    • ssh -fN -L2001:localhost:23 study@192.168.2.207 映射远端23端口到本机2001端口

      • f 端口转发参数
      • N 运行这条命令不占用当前终端
      • 注意: "localhost"的解析,是在ssh连接建立之后,所以,在本地端口转发规则中,"localhost"应该被理解为通过ssh登录到的远端机器
    • ssh -fN -L2002:1.1.1.1:80 study@192.168.2.207 远程映射

      • 将本机的2002通过192.168.2.207这个中间机器映射到1.1.1.1:80机器的80端口上
    • 更多SSH端口转发点这里

    • sshfs study@192.168.2.207:/path/ /mnt 远程挂载目录,临时

      • umount /mnt/myfiles 卸载一,使用root账号
      • fusermount -u /mnt/myfiles 卸载二,使用普通用户权限
    • sudo vim /etc/fstab 修改配置文件,持久挂载

      user@1.1.1.1:/path    /mntpoint    fuse,sshfs    rw,noauto,users,_netdev 0
      

7.3.7 SSH防爆破 {#737-ssh防爆破}

  • 密码爆破防护

    • sudo apt install fail2ban 安装

    • /etc/fail2ban/jail.conf 默认配置文件,软件更新时被覆盖

    • /etc/fail2ban/jail.local 本地配置文件,软件更新不被覆盖,优先级高于默认配置文件,复制于jail.conf文件

      # 全局配置项
      lgnoreip = 127.0.0.1/8 192.168.1.245/24    # 忽略地址(不禁止这些地址),密码错多少次都不会禁止它
      bantime = -1    # 后面加的是时间(秒),当有人连续输错密码超过指定次数后禁止多长时间,-1表示永久禁止
      findtime = 600    # 每隔600秒检查一次日志
      maxretry = 5    # 错误尝试5次
      

    • Jail设置 给每一个服务类型定义一个Jail,优先级高于全局配置项

      • enabled = true 开启单独配置

  • 查看哪些服务开启了jail

    • sudo fail2ban-client status 总览
    • sudo fail2ban-client status sshd 单独的,更详细的
  • 查看防火墙规则

    • sudo iptables -L -n
  • 手动解除被禁IP

    • sudo iptables -D f2b-sshd -s 192.168.2.190-j REJECT

      • D 表示删除规则
      • f2b-sshd 规则名称
      • s 要解除的ip地址
      • j REJECT 拒绝的方式是REJECT,后面写自己防火墙禁用的方式

    • sudo fail2ban-client set sshd unbanip 192.168.2.190

  • 重启服务时读取/var/log/auth.log

    • 在被禁时间内的IP会再次被禁,时间刷新
  • 更多关于fail2ban使用方法请点击这里

7.4 VNC {#74-vnc}

7.4.1 简介 {#741-简介}

  • 图形化界面
    • 使用图形化界面及工具
    • 是Linux系统最通用的远程图形管理工具(适用于Linux、Windows)

7.4.2 安装图形环境 {#742-安装图形环境}

  • sudo apt install gnome-core xfce4 xfce4-goodies tightvncserver
    • gnome-core 最最简化的gnome核心组件
    • xfce4 简化版的图形化界面
    • xfce4-goodies 配合xfce4的小工具
    • tightvncserver vnc服务端的软件包

7.4.3 运行配置 {#743-运行配置}

  • vncserver 命令,启动vnc服务,会生成~/.vnc/xstartup文件

  • ~/.vnc/xstartup 运行配置文件

    • 默认的运行配置文件使用的不是xfce4桌面环境,所以要新建一个运行配置文件,记得备份
  • 创建新运行文件

    1. 创建

      #!/bin/bash
      xrdb $HOME/.Xresources
      startxfce4 &
      

    2. 修改权限

      • chmod +x ~/.vnc/xstartup 增加可执行权限
    3. 运行

      • vncserver 运行vnc服务,记得查看运行的端口号
      • 每运行一次vncserver就新开一个实例,占用一个新端口,如果两个用户连接的vnc服务端口号是相同的,那么他们的远程桌面使用的是同一个桌面,做的操作相互都能看见,如果连接的是两个不同的端口,那相互直接就没关系了
    4. 客户端连接

      • Remmina
      • Remote Desktop Viewer(安装:sudo apt install vinagre)效果比上面好
  • vncserver -kill :1 结束实例

    • VNC服务器启动之后会从5900端口开始往后占用端口,每开启一个新实例就占用一个新端口,例如第一个实例占用5901端口,如果要结束这个实例的话就需要使用:1,这个:1就是5901端口中的1,可用sudo netstat -pantu | grep 590 查看VNC服务端口占用情况

7.5 PUPPET {#75-puppet}

7.5.1 简介 {#751-简介}

  • 全生命周期的远程管理方案
    • 批量的软件安装部署
    • 批量的权限设置
    • 批量的账号管理
    • 支持云平台
    • 支持容器
    • 适合大量服务器管理

7.5.2 准备 {#752-准备}

  • hostnamectl set-hostname puppet 服务器,更改主机名为puppet

  • hostnamectl set-hostname client 客户端,更改主机名为client

  • sudo vim /etc/hosts 服务器和客户端都要新增下面的

    192.168.2.207 puppet.lab.com    	puppet
    # 服务器ip     lab.com可以随便写个 	  服务器主机名
    192.168.2.208 client.lab.com    	client
    # 客户端ip     lab.com保持和服务器一样  客户端主机名
    
    # 可以用DNS服务器来搞,这里改hosts文件只是权宜之计
    

7.5.3 安装 {#753-安装}

  • sudo apt install puppetmaster 服务端
  • sudo apt install puppet 客户端

7.5.4 配置 {#754-配置}

  • 服务端配置-1

    • sudo vim /etc/puppet/modules/apache2/manifests/init.pp

      • 先进入/etc/puppet目录下,然后创建modules/apache2/manifests/目录结构

        • apache2 测试准备给下面的客户端安装apache软件包
        • manifests 存放资源文件的目录
      • 然后创建init.pp这个配置文件

        class apache2{					# 定义一个类叫apache2
            package { 'apache2':		# 定义安装软件包,软件包的名称叫apache2
                ensure => installed,    # 执行安装的操作
            }
        
            service { 'apache2':
                ensure => true,			# 启动apache2服务
                enable => true,
                require => Package['apache2'],	# 需要包的名称[apache2']
            }
        }
        

  • 服务端配置-2

    • sudo vim /etc/puppet/manifests/site.pp

      • 先进入/etc/puppet目录下,然后创建manifests目录
      • 创建site.pp文件,这个文件的作用是选择哪些客户端来执行安装等操作
      node 'client.lab.com' {			# 给client.lab.com对应的ip推送资源
          include apache2				# 执行apache2类中定义的操作
      }
      
      # 可以定义多个node
      

    • sudo systemctl restart puppetmaster.service 重启服务

  • 客户端配置

    • sudo vim /etc/default/puppet
      • 新建puppet配置文件,然后添加下面一行的内容
      • START=yes
    • sudo systemctl restart puppet.service 重启服务

7.5.5 证书、日志查看 {#755-证书日志查看}

  • 客户端证书签名请求测试

    • sudo puppet agent --fingerprint

      • 显示客户端的指纹信息,需要服务器端对这个指纹信息用私钥签名,才能下发证书,客户端用公钥验证身份
      • 客户端的puppet服务在启动的时候就会寻找以puppet开头的服务器,找到之后就会发送自己的指纹信息
    • sudo puppet agent --test

  • 服务端证书请求查看签名

    • sudo puppet cert list 列出证书请求的客户端

    • sudo puppet cert sign client.lab.com 对client.lab.com这个客户端指纹信息签名,签完名就下发了证书

  • 日志状态查询

    • sudo systemctl status puppet.service
    • /var/log/syslog

7.5.6 puppet详解 {#756-puppet详解}

想要知道关于puppet更多的点击这里

第 8 章 DNS服务 {#第-8-章-dns服务}

8.1 域名解析原理 {#81-域名解析原理}

8.1.1 DNS服务 {#811-dns服务}

8.1.2 DNS记录类型 {#812-dns记录类型}

  • NS 域名服务器记录

  • A 主机记录

  • CNAME 别名记录

  • MX 邮件交换记录

  • PTR 指针记录(反向查询)

  • SOA 起始授权记录

    主机记录: www 表示 解析后域名为 www.域名 @表示 直接解析主域名
    *表示泛解析 *.域名

    记录类型: A记录:地址记录,用来指定域名的IPv4地址,如果需要将域名指向一个IP地址,就需要添加A记录。

    CNAME: 如果需要将域名指向另一个域名,再由另一个域名提供ip地址,就需要添加CNAME记录。

    TXT:在这里可以填写任何东西,长度限制255。绝大多数的TXT记录是用来做SPF记录(反垃圾邮件)。

    NS:域名服务器记录,如果需要把子域名交给其他DNS服务商解析,就需要添加NS记录。

    AAAA:用来指定主机名(或域名)对应的IPv6地址(例如:ff06:0:0:0:0:0:0:c3)记录。

    MX:如果需要设置邮箱,让邮箱能收到邮件,就需要添加MX记录。

    显性URL:从一个地址301重定向到另一个地址的时候,就需要添加显性URL记录(注:DNSPod目前只支持301重定向)。

    隐性URL:类似于显性URL,区别在于隐性URL不会改变地址栏中的域名。

    SRV:记录了哪台计算机提供了哪个服务。格式为:服务的名字、点、协议的类型

8.1.3 DNS查询结构 {#813-dns查询结构}

  • 三种DNS服务器

    • Master 负责在域里面对DNS的修改,一般一个域只有一台这样的DNS服务器,会保存这个域中的各种记录

    • Slave Master修改后会同步到Slave的DNS服务器上,会保存这个域中的各种记录

    • Cache 不保存DNS解析记录,一般由运营商提供

      • 下图过程,当打开PC浏览器输入www.baidu.com回车的时候,PC会向首选的DNS服务器发送请求,而这个首选的DNS服务器一般是由运营商分派给你的,一般是一个Cache缓存DNS服务器,它不会存储DNS解析记录,但是会保存根域DNS服务器的IP,当有请求来的时候,会去问根域DNS服务器,根域DNS服务器返回com域DNS服务器的IP,让去问这个,然后这个首选的DNS服务器拿着com域DNS服务器IP去问它了,com域DNS服务器又会返回baidu.com这个域的DNS服务器的IP,让首选的DNS服务器去问它,最后首选的DNS服务器拿着baidu.com域的DNS服务器发起了请求,baidu.com域DNS服务器一看,原来www是我这个域的一个CNAME或主机记录,就将结果返回给了首选DNS服务器,最后的最后首选DNS服务器将最终得到的www.baidu.com对应的ip返回给了PC,PC中的浏览器就向这个IP地址就发起的了请求,这还没玩,当首选DNS服务器(缓存DNS服务器)得到的www.baidu.com这个对应的IP,除了会返回给PC外,自己也会缓存一个这样的对应记录,会有一个生命周期,也就是TTL值,这个TTL值也是由baidu.com域的DNS服务器给的而不是缓存服务器自己说了算的,当在这个生命周期类又有人要访问www.baidu.com时,这个首选的DNS服务器就会直接返回对应的IP地址而不会再去迭代查询,当超过生命周期时,缓存DNS服务器就会自动删除这个对应的记录

    • Forward 转发DNS服务器,也是一种CacheDNS服务器,当有请求的时候,它就将请求转发给另一台缓存DNS服务器,这个转发DNS服务器也会将得到的结果缓存一份

  • 同时是三种角色,同时做Master、Slave、Cache的DNS服务器

8.2 DNS主备部署 {#82-dns主备部署}

8.2.1 安装DNS服务 {#821-安装dns服务}

  • BIND(Berley Internet Naming Daemon) 使用最为广泛的DNS服务软件包(尤其在Linux和Unix上)
  • sudo apt install bind9 dnsutils
    • bind9 DNS服务器软件包
    • dnsutils DNS工具包
    • DNS服务器只保存和解析本域各种域名记录
    • DNS服务器都包含13个根域域名服务器
      • cat /etc/bind/db.root 查看根域的ip地址
      • 事实分布于世界的数百台服务器
    • DNS服务器的DNS服务器配置
      • 自己做迭代
      • 指定递归域名服务器
  • DNS默认服务端口
    • TCP 53 / UDP 53
    • 在查询的时候使用UDP 53端口,当Master和Salve同步的时候使用TCP 53端口
  • BIND的替代方案,其他的DNS服务软件包
    • Djbdns
      • Dbndns、ndjbdns,Djbdns的衍生版本
    • dnsmasq
      • DNS+DHCP打包的轻量解决方案
    • PowerDNS
      • 模块化开源DNS服务器软件

8.2.2 配置Cache DNS服务器 {#822-配置cache-dns服务器}

  • 主配置文件/etc/bind/named.conf

    # 主配置文件只包含下面三行内容,不会有具体的配置项,而是包含其他的配置文件
    
    include "/etc/bind/named.conf.options";
    include "/etc/bind/named.conf.local";
    include "/etc/bind/named.conf.default-zones";
    

  • 全局转发DNS服务器 将请求全部转发

    • sudo vim /etc/bind/named.conf.options
    acl "local" {			# options块之前,local是名字,可以随便取一个,记得是双引号包含
        192.168.2.0/24;		# 本地网段
    };		# acl这一段的作用是在acl里面可以写一些ip地址或网段等,然后后面的就能用local来代表里面的内容,减少重复写ip等,是可以不要的
    
    options {
       recursion yes;		# 开启DNS递归查询
       allow-recursion { local; };		# 允许进行DNS递归查询的地址,local表示上方acl中定义的地址段,除次之外还有any表示运行所有,none表示禁止所有
       listen-on { 192.168.2.207; };	# 假如服务器有多块网卡,这个设置让DNS服务只运行在192.168.2.207这个IP的网卡上
       forwarders {			# 转发对象,当有人向我发起查询请求时而我不知道,就将请求转发给下面的DNS服务器
           9.9.9.9;
           8.8.8.8;
       };
    };
    

  • 区域转发 查询特地单独设置的域名请求不转发

    • sudo vim /etc/bind/named.conf.options
    zone "sina.com.cn" {			# 为sina.com.cn单独配置
    	type forward;		# 类型设置为forward(转发请求)
    	forwards {			# 对于查询sina.com.cn这个域名,将请求转发给下面指定的DNS服务器,而不是全局设置的转发DNS服务器
        	114.114.114.114;
        	233.5.5.5;
        	233.6.6.6;
    	};
    };
    
  • sudo systemctl restart bind9 重启服务

8.2.3 配置Master DNS服务器 正向区域 {#823-配置master-dns服务器-正向区域}

  • 指定区域文件(正向区域------域名解析到IP)

    • sudo vim /etc/bind/named.conf.loacl
    zone "lab.com" {	# 配置一个区域,叫lab.com,可以随便取
    	type master;	# 类型是Master
    	file "/etc/bind/db.lab.com";	# DNS解析的数据存放在/etc/bind/db.lab.com,这个不是强制要求的,放在哪里取什么名字都可以,但是一般都这样做,并且取名字的前面用db开头,后面接域的名字,表示这个文件是后面那个域的DNS解析数据库文件
    };
    

  • 配置区域文件

    • sudo cp db.local db.lab.com 或 sudo db.lab.com 可以从db.local复制一份再编译,或者自己新建一个白手起家然后慢慢添加记录 {#Positive_zone}
    # ; 在此配置文件中表示注释
    ;
    ; BIND data file for lab.com	# 文件说明
    ;
    $TTL    604800		# TTL(Time To Life生命周期),默认单位为秒,1H表示一小时,1D表示一天,1W表示一周等等,这个TTL值就是给缓存(Cache)DNS服务器下的TTL值
    
    # @表示本域的域名,这里就是lab.com
    # IN表示Internet类型,绝大部分都是定义成IN这个类型的,除此之外还有CH,HS不是很常见
    # SOA表示起始授权记录,一般一个域的第一条记录总是SOA,默认情况下后面指定的是localhost.,这里更改为soa.lab.com,前面的soa可以随便取,也不用更改计算机名称为soa,只要soa在这个域中是唯一的即可
    # root.localhost. 表示lab.com这个域DNS管理员的邮箱地址,这里的.表示@
    # com后面的.不能省略,表示根域
    # ()表示一行记录没写下,可以用括号括起来多行来写
    @       IN      SOA     soa.lab.com. root.localhost. (
                                  2         ; Serial	# 表示版本号,用作给Slave类型的DNS服务器同步用的
                             604800         ; Refresh	# 间隔604800秒,Slave类型的DNS服务器会向Master类型(此台服务器)的DNS服务器同步一次
                              86400         ; Retry		# Slave类型的DNS服务器上一次同步没有成功,下一次间隔86400秒就向Master类型(此台服务器)的DNS服务器同步
                            2419200         ; Expire	# Slave类型的DNS服务器在2419200秒之内都未能成功联系上Master类型的DNS服务器,那么Slave类型的DNS服务器中的记录就会过期
                             604800 )       ; Negative Cache TTL	# 协商缓存生存时间,也就是TTL值了,给Slave类型的DNS服务器的而不是缓存DNS服务器
    ;
    # @表示本域
    # IN表示Internet类型
    # NS表示NS记录,就是当前域(lab.com)的域名服务器名称
    # ns1表示NS记录对应的服务器名称,后面不用跟本域(lab.com),因为前面已经有了@表示本域了
    # A表示A记录,一般情况下会给本域(lab.com)设一条A记录,防止别人不使用www.lab.com访问而直接使用lab.com访问
    # AAAA表示4A记录,ipv6地址
    @       IN      NS      ns1
    @       IN      A       192.168.2.1
    ; @       IN      AAAA    ::1
    ns1		IN		A		192.168.2.207
    soa		IN		A		192.168.2.207
    www		IN		CNAME	web
    web		IN		CNAME	W3
    W3		IN		A		192.168.2.1
    # MX表示MX(邮件交换)记录,后面跟一个数字表示优先级,一般用10、20、30...,因为这样中间还可以些其他值(15,23,34...)以防不时之需,首选使用数字小的
    @		IN		MX 10	mx1
    @		IN		MX 20	mx2
    mx1		IN		A		192.168.2.2
    mx2		IN		A		192.168.2.1
    # ftp.lab.com对应两个IP地址,理想状态下解析成IP地址会是这两个IP轮巡,一次是192.168.2.22一次是192.168.2.33
    ftp		IN		A		192.168.2.22
    ftp		IN		A		192.168.2.33
    

  • 服务器配置检查

    • sudo named-checkconf 检查配置文件有没有语法错误
    • sudo named-checkzone lab.com /etc/bind/db.lab.com 正向区域检查,后面跟想检查的域和域对应的db文件
    • sudo named-checkzone lab.com /etc/bind/db.10 反向区域检查,后面跟想检查的域和域对应的db文件

8.2.4 配置Master NS服务器 反向区域 {#824-配置master-ns服务器-反向区域}

  • 反向区域

    • IP解析到域名(反垃圾邮件)
    • sudo vim /etc/bind/named.conf.local
    zone "8.1.10.in-addr.arpa" {	# 创建一个区域,ip要反着写,ip可以写到具体的某一个(192.168.2.1),或者写前三位(192.168.2),或者写前两位(192.168),具体看实际情况,".in-addr.arpa"是必须的
    	type master;	# 类型是Master DNS服务器
    	file "/etc/bind/db.10.1.8";		# DNS解析的数据存放在/etc/bind/db.10.1.8,这个不是强制要求的,放在哪里取什么名字都可以,但是一般都这样做,并且取名字的前面用db开头,后面ip,表示这个文件是后面那个ip的DNS解析数据库文件
    };
    

  • 配置反向区域文件

    ;
    ; BIND reverse data file for local loopback interface
    ;
    $TTL    604800
    @       IN      SOA     ns1.lab.com. root.lab.com. (
                                  1         ; Serial
                             604800         ; Refresh
                              86400         ; Retry
                            2419200         ; Expire
                             604800 )       ; Negative Cache TTL
    ;
    @       IN      NS      ns1.lab.com.
    10      IN      PTR     ns1.lab.com.	# 在/etc/bind/named.conf.local文件中写了192.168.2所以这里的10就表示192.168.2.10,后面的PTR是PTR记录
    2       IN      PTR     mx1.lab.com.
    1       IN      PTR     mx2.lab.com.
    1       IN      PTR     w3.lab.com.
    

8.2.5 配置Slave DNS服务器 {#825-配置slave-dns服务器}

  • 简介

    • 为实现冗余容错,通常会为每个域安装多个Slave DNS服务器
    • 修改记录只在Master上操作,通过版本号通知Slave服务器同步
  • 安全考虑和准备工作

    • Master服务器全局禁止区域传输(禁止客户端下载域名记录)

      • 拒绝一次查询所有的记录,但是一个一个查还是可以的

      • sudo vim named.conf.options

        allow-transfer { none; };
        

    • Master DNS服务器全局禁止区域传输情况下,允许指定IP、指定区域的Slave服务器进行区域传输

      • sudo vim /etc/bind/named.conf.local

        allow-transfer { 192.168.2.1 };
        

    • 区域数据同步使用TCP 53端口

    • Master DNS服务器给将要指定为Slave DNS服务器添加一条ns记录

      • sudo vim /etc/bind/db.lab.com 例如在这个lab.com域中添加一条Slave的ns记录

        ns2		IN		A		192.168.2.190
        
    • dig @ns1.lab.com lab.com axfr 查询lab.com这个区域的所有记录

      ![image](../images/Ubuntu Server/第8章 DNS服务/2-客户端验证解析-1.png)

  • 配置Slave DNS服务器

    • sudo vim /etc/bind/named.conf.options 修改主配置文件
    acl "local" {			# options块之前,local是名字,可以随便取一个,记得是双引号包含
        192.168.2.0/24;		# 本地网段
    };		# acl这一段的作用是将本DNS服务器只给内网192.168.2.0/24这个网段用,防止公网其他人用
    
    options {
       recursion yes;		# 开启DNS递归查询
       allow-recursion { local; };		# 允许进行DNS递归查询的地址,local表示上方acl中定义的地址段
       listen-on { 192.168.2.219; };	# 假如服务器有多块网卡,这个设置让DNS服务只运行在192.168.2.207这个IP的网卡上
       forwarders {			# 转发对象,当有人向我发起查询请求时而我不知道,就将请求转发给下面的DNS服务器
           8.8.8.8;
           9.9.9.9;
       };
    };
    

    • 创建区域,Master上创建了什么区域,Slave上就要创建相同的区域

      • sudo vim /etc/bind/named.conf.local
      # 要和目标Master DNS服务器创建相同的区域
      zone "lab.com" {					# 正向区域
              type slave;					# 类型是slave
              file "db.lab.com";			# 数据文件,注意不要加路径,不需要自己创建,会从Master DNS服务器上同步,保存路径为/var/cache/bind/目录下
              masters { 192.168.2.207; };	# 指定从哪台Master DNS服务器同步数据
      };
      
      zone "2.168.192.in-addr.arpa" {		# 反向区域
              type slave;					# 类型是slave
              file "db.192.168.2";		# 数据文件,注意不要加路径,不需要自己创建,会从Master DNS服务器上同步,保存路径为/var/cache/bind/目录下 
              masters { 192.168.2.207; };	# 指定从哪台Master DNS服务器同步数据
      };
      

  • 记录更新通知

    • Slave服务器到达更新周期啦
    • 客户端数据加密保存(/var/cache/bind/目录下的db文件不能直接修改)
    • Master服务器通知版本号更新
    • sudo vim /etc/bind/named.conf.local Master DNS服务器的配置
    Also-notify { 192.168.2.219; };		# 在所有区域中添加这一行,表示在我这个Master DNS服务器中有版本更新就主动通知192.168.2.219这个Slave DNS服务器
    

8.2.6 客户端验证解析 {#826-客户端验证解析}

  • 正向解析

    • dig命令,Linux默认就有的

      • dig lab.com ns @192.168.2.207 向192.168.2.207的DNS服务器解析lab.com域名的ns记录
      • dig www.lab.com @192.168.2.207 向192.168.2.207的DNS服务器解析www.lab.com的A(默认)记录
      • dig lab.com a @192.168.2.207
      • dig lab.com mx @192.168.2.207
      • dig @ns1.lab.com lab.com axfr 查询lab.com这个区域的所有记录

      ![image](../images/Ubuntu Server/第8章 DNS服务/2-客户端验证解析-1.png)

    • nslookup命令, Windows和Linux默认就有的

      • server 192.168.2.207 DNS服务器
      • set q=ns 查询记录类型a、mx、soa...
      • lab.com 查询目标(域名、FQDN)

      ![image](../images/Ubuntu Server/第8章 DNS服务/2-客户端验证解析-2.png)

    • Windows本地缓存DNS解析结果

      • ipconfig /displaydns 显示缓存的DNS解析结果
      • ipconfig /flushdns 清除缓存的DNS解析结果
    • Ubuntu Linux默认不在本地缓存DNS解析结果

  • 反向解析查询

    • dig -x 要查询的ip @DNS服务器ip 查询PTR记录

第 9 章 文件服务 {#第-9-章-文件服务}

9.1 简介 {#91-简介}

  • 网络诞生最初的动因是去中心化和资源共享
  • 文件是初期最主要的资源共享形式
    • 把文件存放在集中的位置供大家访问
  • 去中心化是另外一个话题
    • 早期的军事需求
    • 现在的信任需求

9.2 FTP服务 {#92-ftp服务}

9.2.1 简介 {#921-简介}

  • File Transfer Protocol(FTP)
    • 早期互联网的重要服务
    • 产生于安全出现之前
    • 明文传输一切
    • 目前主要用于公开提供的文件下载服务
    • 使用简单、兼容性好
    • SFTP、FTPS
  • FTP服务端软件
    • Server U、vsftpd、proftpd
  • 安全考虑
    • 独立部署于企业防火墙之外
    • 只读挂载存储或采用只读存储设备(CD / DVD)

9.2.2 Vsftpd {#922-vsftpd}

  • Vsftpd

    • 灵活、安全的FTP服务端软件
  • 安装

    • sudo apt install vsftpd
    • 安装过程中生成ftp这个名字的账号(anonymous 匿名账号)
      • 在操作系统叫ftp,用ftp的时候叫anonymous,用这个anonymous账号进行匿名登录
  • 叫ftp名字的账号

    • /etc/passwd passwd文件中shell配置位置是 /bin/false ,表示ftp这个账号没有配置shell,也就没法使用shell
    • /etc/shadow shadow文件中的密码部分是个 * ,表示ftp这个账号不能用终端就行登录和远程使用
    • /srv/ftp # ftp名字的用户主目录,不是在home目录下而是在srv下,因为ftp这个名字的账号仅是给FTP服务做匿名登录用的,所以不在home目录下而是在srv目录下

9.2.3 Vsftpd配置 {#923-vsftpd配置}

  • 配置模式

    • anonymous 匿名模式(适用于公开共享文件)
    • Standard 认证模式(需要账号,密码进行登录)
  • 配置文件

    • /etc/vsftpd.conf 主配置文件

    • 匿名模式

      • Vsftpd默认禁止匿名登录
      # 下面两个都要改
      anonymous_enable=YES		# 启用匿名账号登录
      local_enable=NO				# 禁用认证用户登录
      

    • 开启匿名账号上传

      write_enable=YES			# 全局设置(以下配置生效的依赖),取消注释
      anon_upload_enable=YES		# 运行匿名上传文件,取消注释
      anon_mkdir_write_enable=YES	# 运行匿名创建目录,取消注释
      
      # 即使这样ftp客户端也不能上传文件,这是vsftpd的强制要求,具体怎么上传请看下面
      

    • 匿名上传 {#ftp_upload}

      • vsftpd强制禁止在ftp账号的根目录(/srv/ftp/)下匿名上传
      sudo mkdir /srv/ftp/upload	# 创建上传目录
      sudo chown ftp:ftp /srv/ftp/upload	# 配置文件系统权限
      

      • 修改配置文件/etc/vsftpd.conf

        anon_umask=022		# 上传的文件权限掩码,新增配置行
        anon_other_write_enable=YES	# 允许删除和重命名文件/目录,新增配置行
        
  • 修改FTP主目录

    • sudo mkdir /srv/files/

    • sudo vim /etc/files/

      • 将ftp账号那一行的主目录改为/srv/files

    • sudo chown root:ftp files/ 将新建的files目录所有组改为ftp组

    • 但是新建的files目录下也不能上传文件,具体操作点这里

9.2.5 Vsftpd文件传输日志 {#925-vsftpd文件传输日志}

xferlog_enable=YES		# 默认开启
xferlog_file=/var/log/vsftpd.log	# 默认日志目录(可修改),默认是注释的,因为注不注释都会往这里(/var/log/vsftpd.log)写,如果要修改日志位置就取消注释修改

9.2.6 Vsftpd其他配置 {#926-vsftpd其他配置}

idle_session_timeout=600	# 会话超时时间,新增一行
no_anon_passwd=YES			# 命令行登录匿名账号禁用密码提示,新增一行
hide_ids=YES				# 显示属主/属组(默认显示主组的UID)

9.2.7 FTP工作端口 {#927-ftp工作端口}

  • TCP 21 会话指令通信端口

  • 数据传输模式

    • 主动模式 受客户端防火墙影响(防火墙可能会进行地址、端口转换,发出去的地址端口就不是客户端真正提供的地址端口)

      • 传输数据由客户端说了算,服务器用它的20端口连接客户端随机提供的端口
    • 被动模式 兼容性好(建议方式)

      • 传输数据由服务器说了算,客户端连接服务器随机提供的端口

      • 限定被动模式数据通信端口

        # 根据实际情况开多少端口,要在1024-65535之间
        pasv_min_port=40001	# 新增这一行
        pasv_max_port=40100	# 新增这一行
        # 在服务器边界防火墙上开放上述100个端口
        
  • ftp -p 192.168.2.208 被动模式连接

9.2.8 FTP安全 {#928-ftp安全}

  • 默认身份验证用户可回溯到系统根目录(浏览系统所有文件,安全隐患)

    • chroot将登录用户锁定在自己的主目录里
    chroot_local_user=YES	# 取消注释,全局所有的用户都绑定在自己账号的主目录上
    # 但是这样之后就不能登录ftp了,因为如果chroot的根目录(比如登录study账号,那么chroot根目录就是/home/study/目录下)有可写权限,那么vsftpd默认不允许登录在这个目录,解决方法如下,二者选一即可
    
    • 为ftp登录制定新的主目录并减去可写权限

      • sudo mkdir ~/ftp && chmod -w ftp

      • sudo vim /etc/vsftpd.conf

        local_root=/home/study/ftp	# 新增这一行
        
    • 允许chroot根目录写入

      write_enable=YES			# 取消注释,运行写入权限
      local_root=/home/study		# 新增这一行,写不写登录的目录都是/home/study这个目录,前提是登录的是study这个账号
      allow_writeable_chroot=YES	# 新增这一行,允许chroot目录可写,不建议
      
  • 指定chroot的用户列表

    # 被制定的用户账号登录时被锁在自己账号的主目录中,未指定的可以查看系统中所有的目录和文件
    chroot_list_enable=YES		# 开启chroot用户列表,取消注释
    chroot_list_file=/etc/vsftpd.chroot_list	# 指定chroot用户列表文件,取消注释
    
    # ---------------------------------------------------------------------------------------------------------------------------------------------------------#
    
    chroot_local_user=YES	# 全局所有的用户都绑定在自己账号的主目录上,如果启用这一行,那么上面 chroot_list_file 文件中指定的用户是不绑定在自己账号的主目录的,如果没有取消注释,那么上面 chroot_list_file 文件中指定的用户是绑定在自己账号的主目录,作用正好相反
    
    • sudo vim /etc/vsftpd.chroot_list 编辑列表文件,添加用户账号
  • 禁用指定用户账户登录ftp

    • /etc/ftpusers 默认禁止FTP登录账号
      • root、daemon、sys、bin、nobody
    • 将不想让登录ftp的账号加入此文件中就可以了
  • 上传文件权限掩码

    local_umask=022		# 取消注释
    
  • 文件同步客户端

    • ubuntu桌面版自带的 备份软件(dup),自动备份

  • FTPS:FTP over Secure Socket Layer(SSL)

    • 账号无需shell登录权限
  • SFTP:基于SSH加密通道传输文件

    • 账号需要shell登录权限(可设置禁止权限)
  • 开启FTPS

    • sudo vim /etc/vsftpd.conf
    # ftp服务软件在安装的过程中会生成一对密钥,公钥保存在/etc/ssl/certs/ssl-cert-snakeoil.pem,私钥保存在/etc/ssl/private/ssl-cert-snakeoil.key,然后FTP在传输之前,服务器先将公钥发给客户端,客户端用公钥加密之后再发送,服务器再用私钥解密,服务器发送数据之前先用私钥加密,然后发送给客户端,客户端再用公钥解密
    
    ssl_enable=YES		# 启动FTPS,改为YES
    rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem	# 证书,公钥
    rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key			# 私钥
    # 建议生成一张新的证书替换默认的证书,具体方法在下面
    

  • 生成新的证书替换默认证书

    • 安全考虑
    • 生成密钥文件
      • openssl genrsa -des3 -out ftp.key 2048
        • 在Linux下通常使用openssl这个ssl开源组件生成证书及其证书相关的操作
        • genrsa 生成 参数,rsa加密的算法
        • des3 使用des3这个对称的加密算法对生成的秘钥进行加密,对私钥进行加密,为了保密防止私钥泄露
        • 2048 使用2048位的加密长度,也可以写4096等
    • 生成不加密的密钥
      • openssl rsa -in ftp.key -out ftp.key.insecure 将ftp.key使用rsa算法解密成ftp.key.insecure为加密文件
      • mv ftp.key ftp.key.secure 将ftp.key.改名为ftp.key.secure,后面带个secure容易看出这个文件是安全的加密的
      • mv ftp.key.insecure ftp.key将ftp.key.insecure.改名为ftp.key,生成证书的时候就使用这个未加密的key
    • 生成证书请求文件
      • openssl req -new -key ftp.key -out ftp.csr
        • req request请求参数
        • new 生成一个新的证书
        • key 用这个key生成证书
    • 然后将生成的证书提供给一家合法证书颁发机构,审核过了后就会颁发给你,就能使用了,或者自己签名,方法如下

    • 生成自签名证书

      • 就不用将生成的证书提供给第三方证书机构进行审核后颁发了,但是在别人看来是不受信任的
      • openssl x509 -req -days 365 -in ftp.csr -signkey ftp.key -out ftp.pem
        • x509 生成x509标准格式的证书
        • days 有效期
        • signkey 对证书自签名的key
        • ftp.pem 生成pem格式的证书,除此之外还有p7k等很多其他格式

    • 部署证书

      • sudo mv ftp.key /etc/ssl/private/ ftp.key移入到这个目录,其他地方的删掉,防止泄露,是用来解密客户端加了密之后传输过来的数据的
      • sudo cp ftp.pem /etc/ssl/certs/
      • 然后将/etc/vsftpd.conf配置中要用的证书改一下
    • 生产环境建议使用由证书颁发机构签名生成的证书

    • 一行命令

      • sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/vsftpd.key -out /etc/ssl/certs/vsftpd.pem

9.2.9 常见FTP客户端 {#929-常见ftp客户端}

  • 浏览器
    • ftp://anonymous@192.168.2.208 使用匿名账号登录
  • FTP命令
  • FTP客户端程序(Filezilla)
  • 文件同步客户端软件

9.3 NFS服务 {#93-nfs服务}

9.3.1 简介 {#931-简介}

  • NFS ------ Network File System
  • 最早由SUN公司开发
  • 类UNIX平台最主要的文件共享方法
  • 基于RPC(Remote Procedure Call)协议
    • NFS是一个RPC Server(c3 / v4)
    • NFS v4版本已经尽量少使用RPC原始的功能,当然底层的传输数据肯定离不开RPC协议,使用的是TCP 2049端口,RPC隐藏在后面支撑
    • NFS v3版本和RPC协议结合更加的明确,客户端在访问NFS服务时,得先要访问RPC协议的标准端口111,然后映射到NFS的服务端口2049
  • 协议本身不加密,可结合SSH、Kerberos实现加密
  • 隐藏式身份验证
    • 默认用客户端本地用户身份登录NFS服务
  • 权限配置是关键
  • 服务端口 TCP 2049

9.3.2 安装 {#932-安装}

  • sudo apt install nfs-kernel-server # 安装服务端
  • sudo apt install nfs-common # 安装客户端

9.3.3 进程 {#933-进程}

  • rpcbind RPC服务进程
  • nfsd NFS主进程(身份识别)
  • mountd 根据/etc/exports配置来验证客户端登录权限
  • lockd 文件锁定,防止客户端同时编辑一个文件导致文件损坏(需C/S同时启用这个锁定功能)
  • statd 保持文件一致性,保证文件完整性不受到破坏(需C/S同时启用这个一致性功能)

9.3.4 身份识别和权限控制 {#934-身份识别和权限控制}

  • 客户端提供UID / GID ,与用户名、组名无关
    • 例如客户端有个账号zhangsan UID为1001,服务器有个账号lisi UID为1001,那么客户端使用zhangsan账号访问服务器,因为zhangsan账号对应客户端本地的UID为1001,所以最终访问的是服务器UID 1001对应的账号也就是lisi账号
  • 服务器按客户端提供的UID / GID对应服务端本地账号来赋予权限
  • 服务器无客户端提供的UID / GID对应的账号,则将客户端映射为匿名账号
    • nobody / nogroup UID、GID都为65534
  • 客户端使用root账号(UID 0),默认映射为匿名账号
    • 可修改配置文件映射UID 0为服务器端ROOT(存在安全隐患)

9.3.5 配置 {#935-配置}

  • sudo vim /etc/exports

    # /export/public 要共享的目录
    # 192.168.2.0/24 允许访问的地址,可以是单独的ip,IP地址段,域名(例如www.lab.com),还可以使用通配符,(例如*.lab.com),允许所有人访问就写通配符*
    /export/public 192.168.2.0/24(rw,sync,no_subtree_check)		# 这就成功共享了一个目录,如果还要共享其他目录就再添加
    
    # rw可读写权限,ro只读权限
    # sync上传数据时直接写入到硬盘,async上传数据时,先保存到内存,然后再自动写入到硬盘
    # no_subtree_check不检查子目录树(建议使用)
    # all_squash 所有用户全部映射为nobody
    # anonuid / anongid 指定匿名ID(默认65534)
    # secure / insecure 使用1024 以下/以上 端口
    # hide / no_hide 共享/不共享 NFS子目录
    # no_root_sqush 禁用root默认映射为nobody
    

    • sudo mkdir /export/public -p 创建共享目录
    • sudo chown nobody:nogroup /export/public/ 设置权限
    • sudo exportfs 查看已共享的目录
    • cat /var/lib/nfs/etab 查看已共享的目录和权限
    • cat /var/lib/nfs/xtab 查看客户端连接信息

9.3.6 客户端挂载 {#936-客户端挂载}

  • 手动挂载和卸载

    • sudo mount 192.168.2.208:/export/public /nfs/ 挂载到本地nfs目录下
    • sudo umount /nfs/ 取消挂载,卸载
  • 系统启动时自动挂载

    • sudo vim /etc/fstab

      # 使用auto自动挂载会有个问题,当nfs服务器宕机的时候,系统启动时连不上导致启动非常慢,可以改为noauto,等系统启动成功了再手动挂载
      192.168.2.208:/export/public /nfs/ nfs auto,nofail,noatime,nolock,intr,tcp,actime=1800 0 0
      
  • 其他命令

    • rpcinfo -p 192.168.2.208 查询RPC服务注册状态,服务器客户端都可以运行,服务端运行后面写服务端的ip地址,服务端运行后面也可以写localhost
    • tail /var/log/kern.log 显示服务器日志,服务器运行
    • showmount -e localhost 显示共享目录,服务器运行
    • df -h 查看客户端挂载,客户端运行

9.3.7 企业环境 {#937-企业环境}

  • 企业环境有统一域名和身份验证时

    • sudo vim /etc/idpamd.conf

      Domain = lab.com
      
  • Windows客户端

    • 企业版的Windows版本,添加nfs功能

9.4 SAMBA服务 {#94-samba服务}

9.4.1 简介 {#941-简介}

  • SMB/CIFS 协议
    • Server message block / Common internet file system
    • 最早由IBM开发,最后微软采用并不断完善
    • Windows文件和打印共享
    • TCP 139 445 / UDP 137 138
    • SAMBA 是开源世界逆向了SMB协议后打造的兼容微软SMB的文件共享服务
    • SAMBA还有其他功能、用途和使用场景
  • NFS只适用于类UNIX系统环境
  • 适用于Windows、Linux混合环境的文件共享需要
  • SAMBA实现了CIFS服务四个基本功能
    • 文件和打印服务
    • 认证和授权
    • 名称解析
    • 服务宣告(browsing)
  • 传输协议
    • NetBIOS / NetBIOS over TCP/IP(名称解析协议) 局域网 / 跨网段

9.4.2 安装 {#942-安装}

  • sudo apt install samba libpam-winbind

9.4.3 后台进程 {#943-后台进程}

  • Smbd 文件共享主进程 TCP 139 / 445
  • Nmbd WINS通信、名称解析UDP 137 / 138
  • Winbindd 同步系统账号
  • 其他10多个进程

9.4.4 配置文件 {#944-配置文件}

  • 配置文件在/etc/samba/目录下

    • dhcp.conf 指定WINS服务器
      • WINS服务器:微软用来解析NetBIOS名称到ip地址的服务器的ip地址
    • smb.conf 主配置文件
  • smb.conf 场景一:每个人用自己的账号密码登录,从而获得不同的权限

    workgroup = WORKGROUP		# 在[global]下面,后面写Windows的工作组,可在Windows上面输入命令net config workstation或者右键计算机选属性查看,Windows默认没配置就是WORKGROUP
    
    [private]					# 共享文件夹的共享名称,Windows访问时看到的文件夹名称
      comment = private			# 描述,一段描述信息
      path = /srv/private/		# 共享路径
      browseable = yes			# 可浏览(完整路径),是否允许访问者能看见共享文件夹,让大家知道有这么个共享文件夹,设为no的话只能通过路径访问
      guest ok = no				# 禁用来宾账号
      writeable = yes			# 可读写(read only = yes 只读)
      create mask = 0755		# 新建文件权限
      valid users = @samba		# 可访问共享的用户组,只允许samba组用户能访问
    
    • sudo adduser smb1 创建访问smb服务器的用户
    • sudo groupadd samba 创建samba组,要和配置文件中设置的组一样
    • sudo gpasswd -a smb1 samba 将smb1账号 3加入到samba组中
    • sudo smbpasswd -a smb1 设置用户SMB密码(不同于系统账号密码)
    • sudo mkdir /srv/private/ 创建共享路径
    • sudo setfacl -R -m "g:samba:rwx" /srv/private/ 设置组ACL权限,设置完成后ls -l权限最后会有个+号,使用getfacl查看权限
    • testparm 测试samba配置
    • sudo systemctl restart smbd.service nmbd.service 重启服务

  • smb.conf 场景二:每个人都能访问,开放的共享文件夹

    • 将不提供登录账号的用户映射为guest账号,无需输入密码,匿名登录
    # 在Global下面增加这些配置
    [Global]
    workgroup = WORKGROUP
    security = user				# 设置安全类型
    # user 表示输入账号密码来进行访问,
    # share 是早期版本客户端使用guest账号来访问目标服务器,现在新版已废止
    # Domain 把samba放到微软的域里面,可以吧samba做成一个PDC、BDC成员服务器,在这样一个域环境下进行工作(不常用)
    # ADS 微软的活动目录域(不常用)
    # Server 在samba成为域,加入微软活动目录之前临时存在的安全状态(不常用)
    map to guest = bad user		# 当客户端访问没有账号密码的时候就map to guest映射为guest
    guest ok = yes				# 允许guest用户访问
    
    
    # 开放共享文件夹
    [public]					# 共享文件夹的共享名称,Windows访问时看到的文件夹名称
      comment = public share	# 描述,一段描述信息
      path = /srv/public/		# 共享路径
      browseable = yes			# 可浏览(完整路径),是否允许访问者能看见共享文件夹,让大家知道有这么个共享文件夹,设为no的话只能通过路径访问
      guest ok = yes			# 启用来宾账号
      writeable = yes			# 可读写(read only = yes 只读)
    
    • sudo mkdir /srv/public/ 创建共享路径
    • sudo setfacl -R -m "u:nobody:rwx" /srv/public/ 设置组ACL权限,设置完成后ls -l权限最后会有个+号,使用getfacl查看权限
    • testparm 测试samba配置
    • sudo systemctl restart smbd.service nmbd.service 重启服务

9.4.5 连接samba服务器 {#945-连接samba服务器}

  • Windows客户端
    • net use 查看已连接的
    • net use \\host\directory /user:smb1 passwd 使用用户名密码连接
    • net use \\host\directory /delete 删除一个连接
    • net use x: \\host\directory 连接并挂载到x盘
      • net use x: /delete 删除挂载
    • net config workstation 查看Windows工作域
    • 在windows资源管理器里面输入:\\host
  • Linux客户端
    • smbclient -L //host 连接
    • smbclient -L //host -U smb1 使用smb1账号登录
    • sudo mount -t cifs -o username=smb1 //host/directory /mnt 使用smb1连接并挂载到本地mnt目录下

9.4.6 服务器信息 {#946-服务器信息}

  • smbd --version 查看Samba版本
  • sudo smbstatus 查看Samba状态

第 10 章 WEB服务 {#第-10-章-web服务}

10.1 WWW介绍 {#101-www介绍}

10.1.1 WWW万维网 {#1011-www万维网}

  • 使用最广泛的网络应用
  • C / S架构
  • B / S架构(Firefox、Opera、Chromium、Internet Explorer、Edge)
    • 服务器端接受客户端提交请求,计算处理后返回响应结果
    • 客户端使用统一的浏览器发出标准请求格式,并对服务器返回结果渲染呈现
  • 静态网站
    • 所有人看到的内容都一样
  • 动态应用程序
    • 数据库、中间件
    • 每个用户看到的内容不同
    • 根据用户的输入返回不同的结果

10.1.2 访问方式 {#1012-访问方式}

10.1.3 HTTP协议 {#1013-http协议}

  • HTTP(HyperText Transfer Protocol)
    • 明文协议(无内建机密性安全机制)
    • HTTPS提供传输层安全(SSL / TLS)
  • 请求方法
    • Get
    • Post
    • Put 上传文件
    • Delete 删除文件
    • Options 服务器会将所支持的方法返回给客户端
    • Header 服务器只发送头部的数据
    • ...
    • Get / http/1.1
  • 无状态
    • 每一次B / S间通信都是独立的过程
    • 通过Session对身份验证后用户行为跟踪(否则每次请求都要验证身份)
  • HTTP头部
    • Host:主机IP / 名称
    • Cookie:客户端发回给服务器证明用户状态的信息(头:值成对出现)
    • Referrer:发起新请求之前用户位于哪个页面
    • Set-Cookie:服务器发给客户端的SessionID
    • Content-Length:响应body部分的字节长度
    • Location:重定向用户到另一个页面
  • 服务端响应表示结果的状态码(5大类50多个具体响应码)
    • 100s:信息,通常表示服务器还有后续处理,不常出现
    • 200s:成功响应
    • 300s:重定向,301永久重定向 / 302临时重定向(location)
    • 400s:客户端请求错误
      • 401:需要身份验证
      • 402:拒绝访问
      • 404:目标未发现
    • 500s:服务器内部错误(503:服务不可用)
    • http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

10.2 APACHE2 {#102-apache2}

10.2.1 简介 {#1021-简介}

  • 北美印第安人的第一个部落 / 美军武装直升机
  • Apache软件基金会的第一个开源WEB服务器
  • 世界使用排名第一的WEB服务器软件?
  • 模块化强大的扩展能力
    • SSO模块
    • 并发限制模块
    • 日志监控模块
    • WAF模块
    • 负载均衡模块
    • 音乐/图像处理模块

10.2.2 安装 {#1022-安装}

  • sudo apt install apache2

10.2.3 侦听端口 {#1023-侦听端口}

  • TCP 80

10.2.4 配置文件 {#1024-配置文件}

  • 通过众多directives(指令)进行配置

    • Directives分散于多个配置文件中
  • 配置文件(/etc/apache2/)

    • 本质上配置指令可以位于任何一个配置文件中
    • apache2.conf 主配置文件,全局配置(Include其他配置文件)
    • httpd.conf 新版本已弃用
    • conf-available 可用的配置目录
    • conf-enable 启用的配置目录(需重启服务)
    • Envvars 环境变量
    • mods-available 可用的模块目录
    • mods-enabled 启用的模块目录(需重启服务)
    • ports.conf WEB服务侦听端口
    • sites-available 可用的站点目录(虚拟主机)
    • sites-enabled 启用的站点目录(需重启服务)
    • magic 根据文件前几个字符确定MIME类型
  • 站点默认配置

    • /etc/apache2/sites-available/000-default.conf 默认虚拟主机
    <VirtualHost>			# 设置一个虚拟主机时的标签
        ServerName				# 设置主机头
        DocumentRoot			# 制定WEB根目录
        ErrorLog				# 报错日志
        CustomLog				# 访问日志
        ServerAdmin				# 报错时显示的管理员邮箱
    </VirtualHost>	
    

  • 创建两个新的虚拟主机

    • 计划:创建两个虚拟主机分别是www.ali.com和www.baidu.com都运行在这台服务器上相同ip和端口上(根据http请求中的host来分辨客户端访问的是哪个网站)
    • sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/ali.conf 复制一份成ali.conf
    <VirtualHost *:80>						# *:80表示运行在本地所有网卡ip上的80端口
            ServerName www.ali.com			# 只能通过www.ali.com访问
    
            ServerAdmin webmaster@ali.com	# 报错时显示的管理员邮箱
            DocumentRoot /var/www/ali		# 网站根目录
    
            ErrorLog ${APACHE_LOG_DIR}/error.log			# 报错日志位置
            CustomLog ${APACHE_LOG_DIR}/access.log combined	# 访问日志位置
    </VirtualHost>
    

    • sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/baidu.conf 复制一份成baidu.conf
    <VirtualHost *:80>						# *:80表示运行在本地所有网卡ip上的80端口
            ServerName www.ali.com			# 只能通过www.baidu.com访问
    
            ServerAdmin webmaster@ali.com	# 报错时显示的管理员邮箱
            DocumentRoot /var/www/ali		# 网站根目录
    
            ErrorLog ${APACHE_LOG_DIR}/error.log			# 报错日志位置
            CustomLog ${APACHE_LOG_DIR}/access.log combined	# 访问日志位置
    </VirtualHost>
    

    • sudo mkdir /var/www/ali/ && sudo mkdir /var/www/baidu/ 创建www.ali.com网站根目录和创建www.baidu.com网站根目录
    • sudo a2ensite ali && sudo a2ensite baidu 启用ali和baidu两个虚拟主机
      • sudo a2dissite mysite 停用虚拟主机
    • sudo systemctl reload apache2 重新reload
    • sudo systemctl restart apache2.service 重启服务
  • 修改默认首页

    • sudo vim /etc/apache2/mods-available/dir.conf 默认索引页配置文件

  • 禁用列出目录

    • sudo vim /etc/apache2/apache2.conf
    <Directory /var/www/>
            Options Indexes FollowSymLinks		# 将 Indexes 去掉,这样当主默认页面文件不存在时就不会将目录的内容列出来了,而是会报Permission Denied权限拒绝的错误
            AllowOverride None
            Require all granted
    </Directory>
    

  • 更改报错提示

    • sudo vim /etc/apache2/conf-available/localized-error-pages.conf
    # 一个例子
    ErrorDocument 404 "/m.html"		# 当出现404错误时,就返回网站根目录下的m.html文件
    
  • 基于目录的options

    • sudo vim /etc/apache2/apache2.conf
    <Directory /var/www/>
            Options Indexes FollowSymLinks ExecCGI Includes
            # 在Options后面可放置的选项
            # ExecCGI 允许CGI脚本执行(默认只允许/usr/lib/cgi-bin/下的CGI可以执行,建议)
    		# Includes 允许服务端包含(一个html包含另一个html)
    		# IncludesNOEXEC 允许包含,但禁用CGI脚本exec、include的权限
            AllowOverride None
            Require all granted
    </Directory>
    
  • 环境变量

    • sudo vim /etc/apache2/envvars
    # 服务器端应答客户端访问的账号(默认使用www-data账号)
    export APACHE_RUN_USER=www-data
    export APACHE_RUN_GROUP=www-data
    
    # apache2允许的pid /var/run/apache2/apache2.pid
    export APACHE_PID_FILE=/var/run/apache2$SUFFIX/apache2.pid
    
    # 并发最大打开的文件数
    APACHE_ULIMIT_MAX_FILES='ulimit -n 65536'
    
  • 模块化

    • 服务器核心只实现了基本功能
      • apache2 -l 查看核心的基本模块
    • 其他功能通过模块实现
    • Ubuntu编译动态加载模块实现运行时模块调用
    • apt search libapache2-mod 搜索模块,搜索出所有的apache模块
    • sudo apt install libapache2-mod-auth-mysql 安装模块
    • sudo a2enmod auth_mysql 启用模块
    • sudo a2dismod auth_mysql 禁用模块

10.2.5 配置https {#1025-配置https}

  • 传输过程的 C I A(机密性 完整性 可用性)

    • 不提供应用层安全
  • /etc/apache2/sites-available/default-ssl.conf 默认配置好了的https配置文件

    • sudo a2ensite default-ssl 启用默认配置好了的https配置的虚拟主机站点,默认未启动
    • sudo a2enmod ssl 启用ssl模块,默认未启动
    # 下面仅对配置说明,不是这样配置的
    _default_:443    # 未指定虚拟主机的443端口访问
    # default 表示如果配置了多个https虚拟主机通过域名(HTTP请求HOST字段判断)访问,加入没有通过域名
    
    SSLEngine on	# 开启SSL / TLS
    
    # ssl证书和密钥
    SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem			# 证书
    SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key	# 秘钥
    
    SSLCertificateChainFile /etc/apache2/ssl.crt/server-ca.crt		# 指定证书信任链,比如你的证书服务器是第三级的证书服务器,那么要第一级的证书服务器信任第二级的证书服务器信任第三级的证书服务器,这个是由证书颁发机构给你的,当然自签名证书就不用配置这个了,这个是对于公网上的证书
    
    # 证书吊销列表,一般一张证书使用3,5年之后就不用,当过了有效期的时候证书就要吊销,要吊销的时候就要用到这个CRL来验证
    SSLCACertificatePath /etc/ssl/certs/
    SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt
    
    # 要求客户端访问时也要提供一个证书证明自己
    SSLVerifyClient require
    
    # 基于某种文件类型对它的SSL选项进行适当的配置
    <FilesMatch "\.(cgi|shtml|phtml|php)$">
    	SSLOptions +StdEnvVars
    </FilesMatch>
    # StdEnvVars 使用标准的环境变量
    
    # 基于某些目录对它的SSL选项进行适当的配置
    <Directory /usr/lib/cgi-bin>
    	SSLOptions +StdEnvVars
    </Directory>
    
    # 当要断开连接的时候,客户端发送一个断开请求,服务器收到后就直接断开了,这样性能会好些,可靠性降低
    ssl-unclean-shutdown
    # 服务器给客户端发送断开请求,客户端返回确认信息,然后客户端再发送断开请求,服务器再返回确认信息,这样做对连接的稳定性和可靠性高些,性能低些
    ssl-accurate-shutdown
    # 对特定的浏览器进行设置
    BrowserMatch "MSIE [2-6]" \		# MSIE [2-6] 表示IE浏览器2-6的古老版本
    	nokeepalive ssl-unclean-shutdown \	# nokeepalive不进行长连接的保持
    	downgrade-1.0 force-response-1.0	# downgrade-1.0 把http降级为1.0版本,force-response-1.0强制响应为http 1.0版本
    
    
  • 证书

    • CA机构签名证书

      • sudo openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr 生成证书拿去给CA机构签名
    • 自签名证书 {#10.2.5 配置https_1}

      • 命令:sudo openssl req -x509 -nodes -days 365 -sha256 -newkey rsa:2048 -nodes -keyout /etc/ssl/private/mysite.key -out /etc/ssl/certs/mysite.crt

        | 命令及参数 | 功能 | |-------------------------------------|-----------------------------| | openssl | 使用openssl生成证书 | | req | 请求,请求生成一张证书 | | -x509 | 生成x509标准格式的证书 | | -days 365 | 证书有效期是365天 | | -sha256 | 使用哈希256位算法 | | -newkey rsa:2048 | 生成key文件,使用非对称加密rsa 2048位算法 | | -nodes | 这是一张节点证书,服务器证书 | | -keyout /etc/ssl/private/mysite.key | key文件(私钥)保存位置,key文件名称可以随意命名 | | -out /etc/ssl/certs/mysite.crt | 证书保存位置 |

      • 生成证书需要绑定某一个主体,表示这张证书是为了某一个对象实现加密服务的,所以在过程中填写

        | 问题 | 解析 | 参考 | |--------------------------------------------------------------|------|---------------------------------------| | Country Name (2 letter code) [AU] | 国家信息 | CN | | State or Province Name (full name) [Some-State] | 省信息 | AnHui | | Locality Name (eg, city) [] | 城市信息 | HeFei | | Organization Name (eg, company) [Internet Widgits Pty Ltd] | 公司信息 | qq.com | | Organizational Unit Name (eg, section) [] | 部门信息 | Security | | Common Name (e.g. server FQDN or YOUR name) [] | 绑定域名 | www.lab.com | | Email Address [] | 邮件地址 | admin@lab.com |

      • 生成证书完毕,绑定了某一域名(这里是www.lab.com),那么下次只能通过这个指定的域名(这里是www.lab.com)去访问这张证书保护的Web站点,否则就会有证书错误的报错,绑定的域名一定要写要保护的Web站点域名

  • 创建HTTPS虚拟主机

    • sudo cp /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-available/mysite-ssl.conf 复制一份默认的https然后再编辑配置文件
    # 根据自己的需要修改配置文件
    <VirtualHost *:443>			# *表示在所有的网口上侦听443端口
    ServerName www.lab.com:443	# 网站的名称
    SSLCertificateFile
    /etc/ssl/certs/mysite.crt	# 指定证书
    SSLCertificateKeyFile /etc/ssl/private/mysite.key
    

10.2.6 证书 {#10.2.6 证书_1}

  • 商业证书颁发机构
    • 权威机构颁发、默认受信、增强特性、收费高昂、有效期长(数年)
  • Let's encrypt
    • 致力于加速全网实现HTTPS的免费证书颁发机构
    • 证书有效期90天(可刷新)
    • 专门客户端程序 Certbot
    • 安装客户端
      • sudo add-apt-repository ppa:certbot/certbot 添加库**(不需要了,直接安装)**
      • sudo apt install python-certbot-apache 安装客户端(自动获得安装证书)
    • 前提
      • 域名正常解析、设置好虚拟主机
    • 申请并获得证书
      • sudo certbot --apache -d example.com -d www.example.com
        • -d 指定域名,可以指定多个域名
    • 证书位置
      • /etc/letsen crypt/live
    • 查看证书状态

10.2.7 让Apache支持PHP {#10.2.7 让Apache支持PHP_1}

  1. 让Apache支持PHP

    1. 命令:sudo apt install php7.2 libapache2-mod-php7.2 安装Apache支持PHP模块,通过安装Apache的libapache2-mod-php7.2模块,这个模块就将Apache收到的PHP请求发送给PHP运行程序处理,而不是像Nginx那样还要在配置文件中配置转发请求
    2. 命令:php -v 验证PHP安装是否成功
    3. 命令:a2enmod php7.2 启用模块
  2. PHP配置文件

    • 安装完PHP之后,在**/etc/php/7.2/目录下的多个目录中都有 php.ini**配置文件,在/usr/lib/php/7.2/目录下也有php.ini配置文件

    • 在实际过程中通常将**/usr/lib/php/7.2/目录下的配置文件在 /etc/php/7.2/目录下的各个子模块目录中创建一个链接,这样只要维护/usr/lib/php/7.2/**下的配置文件就可以了,其他地方不在需要单独配置

    • /etc/php/7.2/目录下apache2,cli,fpm 目录下的php.ini都有什么作用?

      • apache2目录下的php.ini是针对于Apache服务器调用PHP时使用的
      • cli目录下的php.ini,是针对于在命令行中执行php时的配置
      • fpm目录下的php.ini,是针对于Nginx服务器调用PHP时使用的

10.3 Keepalived {#103-keepalived}

10.3.1 简介 {#1031-简介}

  • 实现高可用(HA)
    • 在服务器组内漂移的 VIP
      • VIP:虚拟ip,不是真实在网卡上的ip,是一个随机的ip,当第一台服务器可用的时候这个vip就由第一台服务器占有,当第一台服务器关机了,那么这个vip就由第二台服务器占有
    • Master 独占 VIP,其他 Server 检查 Master 可用性
    • Keepalived 并非专门针对 Apache 而设计
    • 常用于负载均衡技术环境
    • 组内服务器应提供相同内容和配置

10.3.2 安装 {#1032-安装}

  • sudo apt install keepalived
  • 因为无配置,所以默认启动失败
  • /etc/keepablive/keepalived.conf 配置文件(需要创建)

10.3.3 配置文件 {#1033-配置文件}

  • sudo vim /etc/keepablive/keepalived.conf
# 配置一个邮件服务器,当有服务器出问题了,就会发送一封邮件给管理员,当然不配置这个也是完全没问题的
global_defs {				# 设置一个全局配置项
    notification_email {	# 邮件通知
    myemail@mycompany.com	# 通知的邮箱地址
    }
    notification_email_from keepalived@mycompany.com	# 邮件发件人
    smtp_server 192.168.1.150	# 邮件服务器ip
    smtp_connect_timeout 30		# 邮件服务器连接超时时间
    router_id mycompany_web_prod
}

# VI_1号配置实例
vrrp_instance VI_1 {
    smtp_alert				# 如果出问题了,就调用上面的邮件配置发送邮件
    interface enp0s3		# 在哪个网卡上进行工作
    virtual_router_id 51	# 定义服务器组,数字可以随便写,但是同一个组的服务器这个id数字必须一样,也就是通过这个数字来划分组的
    priority 100			# 当前服务器在组中的优先级,越大优先级越高
    advert_int 5			# 通告间隔5秒
    virtual_ipaddress {
    	192.168.1.200		# 设置VIP(不要写DHCP自动分发的ip地址,以免发生冲突)
    }
}

  • sudo systemctl restart keepalived.service 重启服务

  • sudo systemctl status -l keepalived.service 查看状态

  • 查看网卡绑定的VIP

    • ip a
    • 等待30秒

  • 再在第二台服务器上配置keepallve

  • 模拟切换

    • 命令:sudo sudo systemctl stop keepalived.service
    • 命令:sudo systemctl start keepalived.service

10.4 Nginx {#104-nginx}

10.4.1 简介 {#1041-简介}

  • 开源、轻量、快速、可扩展的WEB服务器
  • GitHub、Netflix、wordpress都基于nginx
  • 可配置能力弱于Apache
  • 适用于大流量、高并发环境
    • 稳定快速、占用资源少(C10K问题------1W的并发访问量)
  • 在Top1000个网站中使用率最高(37%)
  • Apache基于线程
    • 基于进程消耗资源多
    • 同进程下的多线程共享内存(一损俱损)
  • nginx使用事件驱动的架构
    • 新客户端请求时不创建新的进程、线程
    • 事件处理器处理请求任务
    • 更少的处理时间、更少的内存消耗
  • Apache与Nginx共用
    • Apache处理动态内容
    • Nginx处理静态内容

10.4.2 安装 {#1042-安装}

  • 命令:sudo apt install nginx

10.4.3 配置文件 {#1043-配置文件}

  • 注意:nginx -s relaod 热加载nginx的配置文件,不需要重启

  • 命令:sudo nginx -t 用来检查配置文件有没有语法错误

  • 基于虚拟主机的配置

    • /etc/nginx/nginx.conf 主配置文件(包含其他配置文件)
    • /etc/nginx/sites-available/ 可用的虚拟主机 (server blocks)
    • /etc/nginx/sites-enabled/ 启用的虚拟主机
    • /etc/nginx/snippets/ 需要复用的配置片段
    • /etc/nginx/site-enabled 已启用站点
    • /var/log/nginx/access.log 访问日志
    • /var/log/nginx/error.log 错误日志

  • /etc/nginx/nginx.conf 主配置文件(包含其他配置文件)

    user www-data;				# nginx进程账号
    worker_processes auto;		# 进程数,默认为auto自动
    pid /run/nginx.pid;			# pid所在位置
    include /etc/nginx/modules-enabled/*.conf;	# include包含其他配置文件
    
    events {							# 事件相关配置
            worker_connections 768;		# 一个进程最大的连接数
            # multi_accept on;
    }
    
    http {								# http相关配置
    
            ##
            # Basic Settings
            ##
    
            sendfile on;				# 内核实现(静态性能主要来源)
    
            # 下面两个参数的意思是:当有大量的请求来的时候,可以把一个包填满的时候就用tcp_nopush,但是当传输包所有的总量不是1460的整数倍,最后还剩一点字节的时候,那么最后剩的一点字节就组成一个包(最后一个包)使用tcp_nodelay,不等待就直接发出去了
            tcp_nopush on;				# 优化发包大小,提高性能,接收到一个后如果返回的数据包不够1460个字节大小,会等待0.2秒,看还有没有请求,如果有接收多个请求然后一次把响应都发回,所以和tcp_nodelay是互斥的
            tcp_nodelay on;				# 优化发包延时(不等0.2秒),和上面的参数互斥
    
            keepalive_timeout 65;		# 每个连接保持时间(大访问小赋值)
            types_hash_max_size 2048;	# mime类静态内容HASH表大小
            # server_tokens off;
    
            # server_names_hash_bucket_size 64;
            # server_name_in_redirect off;
    
    		# nginx给每一个静态内容都计算一个HASH值存在缓存中,利用缓存的快速读取,尽最快的速度匹配客户端查询的内容
            include /etc/nginx/mime.types;		# 包含mime类型的文件包含进来
            default_type application/octet-stream;
    
            ##
            # SSL Settings
            ##
    
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
            ssl_prefer_server_ciphers on;
    
            ##
            # Logging Settings
            ##
    
            access_log /var/log/nginx/access.log;
            error_log /var/log/nginx/error.log;
    
            ##
            # Gzip Settings
            ##
    
            gzip on;					# 启用压缩(加快传输速度)
    
            # gzip_vary on;
            # gzip_proxied any;
            # gzip_comp_level 6;
            # gzip_buffers 16 8k;
            # gzip_http_version 1.1;
            # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    
            ##
            # Virtual Host Configs
            ##
    
            include /etc/nginx/conf.d/*.conf;
            include /etc/nginx/sites-enabled/*;
    }
    
    
    #mail {
    #       # See sample authentication script at:
    #       # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
    #
    #       # auth_http localhost/auth.php;
    #       # pop3_capabilities "TOP" "USER";
    #       # imap_capabilities "IMAP4rev1" "UIDPLUS";
    #
    #       server {
    #               listen     localhost:110;
    #               protocol   pop3;
    #               proxy      on;
    #       }
    #
    #       server {
    #               listen     localhost:143;
    #               protocol   imap;
    #               proxy      on;
    #       }
    #}                                                          
    

10.4.4 虚拟主机配置 {#1044-虚拟主机配置}

  • /etc/nginx/site-enabled/ 已启用站点

    # 默认启用的站点配置 /etc/nginx/site-enabled/default
    
    server {
            listen 80 default_server;		# 侦听80端口
            listen [::]:80 default_server;
    
            root /var/www/html;		# 站点根目录
    
            # Add index.php to the list if you are using PHP
            index index.html index.htm index.nginx-debian.html;		# 首页的文件
    
            server_name _;	# 虚拟主机名(比如www.a.com)
    
            location / {
                    # First attempt to serve request as file, then
                    # as directory, then fall back to displaying a 404.
                    try_files $uri $uri/ =404;	# 先找请求的目标然后返回,如果没有就是返回目录列表,如果目录中也没有请求的目录就返回404
            }
    }
    

10.4.5 新建虚拟主机( Server Blocks ) {#1045-新建虚拟主机-server-blocks-}

  • 例如新建一个qq.com的站点
  1. 先进入到**/etc/nginx/sites-available**目录下,执行命令:sudo cp default qq.com,将复制一份默认的配置文件,然后在复制后的文件上修修改改,减少写配置的操作

  2. 打开复制的qq.com配置文件,进行修改,比如

    ##
    # You should look at the following URL's in order to grasp a solid understanding
    # of Nginx configuration files in order to fully unleash the power of Nginx.
    # https://www.nginx.com/resources/wiki/start/
    # https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
    # https://wiki.debian.org/Nginx/DirectoryStructure
    #
    # In most cases, administrators will remove this file from sites-enabled/ and
    # leave it as reference inside of sites-available where it will continue to be
    # updated by the nginx packaging team.
    #
    # This file will automatically load configuration files provided by other
    # applications, such as Drupal or Wordpress. These applications will be made
    # available underneath a path with that package name, such as /drupal8.
    #
    # Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
    ##
    
    # qq.com server configuration
    #
    server {
    	listen 80;	# 删除80后面default_server,和下一行的IPV6 80端口的侦听,只侦听IPV4的80端口
    
    	# SSL configuration
    	#
    	# listen 443 ssl default_server;
    	# listen [::]:443 ssl default_server;
    	#
    	# Note: You should disable gzip for SSL traffic.
    	# See: https://bugs.debian.org/773332
    	#
    	# Read up on ssl_ciphers to ensure a secure configuration.
    	# See: https://bugs.debian.org/765782
    	#
    	# Self signed certs generated by the ssl-cert package
    	# Don't use them in a production server!
    	#
    	# include snippets/snakeoil.conf;
    
    	root /var/www/qq.com/;	# 修改本站点的页面文件存放在哪个目录下
    
    	# Add index.php to the list if you are using PHP
    	index index.html index.htm index.nginx-debian.html;	# 默认索引页面,修改成自己的或者用默认的都OK
    
    	server_name www.qq.com;	# 设置服务器名称,因为默认站点和这个站点都侦听80端口如果不设置服务器名称就会出问题,为了区分这两个站点让用户访问到自己想访问的站点,就要给这个新创建的站点取一个自己的服务器名称
    
    	location / {
    		# First attempt to serve request as file, then
    		# as directory, then fall back to displaying a 404.
    		try_files $uri $uri/ =404;
    	}
    
    	# pass PHP scripts to FastCGI server
    	#
    	#location ~ \.php$ {
    	#	include snippets/fastcgi-php.conf;
    	#
    	#	# With php-fpm (or other unix sockets):
    	#	fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
    	#	# With php-cgi (or other tcp sockets):
    	#	fastcgi_pass 127.0.0.1:9000;
    	#}
    
    	# deny access to .htaccess files, if Apache's document root
    	# concurs with nginx's one
    	#
    	location ~ /\.ht {	# 取消这个的注释,通常来说是打开的,这个配置是访问控制,意思是访问以.ht结尾的文件就拒绝访问
    		deny all;	# 拒绝访问,可以设置允许或拒绝访问
    	}
    }
    
    
    # Virtual Host configuration for example.com
    #
    # You can move that to a different file under sites-available/ and symlink that
    # to sites-enabled/ to enable it.
    #
    #server {
    #	listen 80;
    #	listen [::]:80;
    #
    #	server_name example.com;
    #
    #	root /var/www/example.com;
    #	index index.html;
    #
    #	location / {
    #		try_files $uri $uri/ =404;
    #	}
    #}
    
  3. 创建在配置文件中指定的页面存放目录,命令:sudo mkdir /var/www/qq.com

  4. 然后进入到sudo mkdir /var/www/qq.com 目录下,将站点页面文件放进去,这里为了简单掩饰就新建一个index.html ,写个Hello qq.com,用来访问时识别的

  5. 启用配置的站点,进入到**/etc/nginx目录下,将 sites-available中的配置文件在 sites-enabled目录下创建一个链接,只有在 sites-enabled目录下才是启用的站点,在 sites-available**目录下只是可用的站点,命令:sudo ln -s /etc/nginx/sites-available/qq.com /etc/nginx/sites-enabled/qq.com,前面的地址要写绝对路径

  6. 修改本机**/etc/hosts文件,将 www.qq.com**指向本机地址,这样浏览器访问**www.qq.com**时Nginx就会将相应的站点显示出来了

10.4.5 让Nginx支持PHP及PHP简单配置 {#1045-让nginx支持php及php简单配置}

  • 让Nginx支持PHP

    1. 命令:sudo apt install php-fpm 安装让Nginx支持PHP的软件包,Nginx与PHP配合一般都使用fastCGI process manager 这个软件包,与PHP结合起来名字就叫做了php-fpm

    2. 查看本机上PHP进程的名称,命令:ls /var/run/php ,以**.sock结尾的名称就是PHP进程的名称,不同版本的PHP所显示的进程名称也不同,这里是php7.2-fpm.sock**

    3. 打开站点Nginx的配置文件,/etc/nginx/sites-available/qq.com

      ##
      # You should look at the following URL's in order to grasp a solid understanding
      # of Nginx configuration files in order to fully unleash the power of Nginx.
      # https://www.nginx.com/resources/wiki/start/
      # https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
      # https://wiki.debian.org/Nginx/DirectoryStructure
      #
      # In most cases, administrators will remove this file from sites-enabled/ and
      # leave it as reference inside of sites-available where it will continue to be
      # updated by the nginx packaging team.
      #
      # This file will automatically load configuration files provided by other
      # applications, such as Drupal or Wordpress. These applications will be made
      # available underneath a path with that package name, such as /drupal8.
      #
      # Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
      ##
      
      # Default server configuration
      #
      server {
      	listen 80;
      
      	# SSL configuration
      	#
      	# listen 443 ssl default_server;
      	# listen [::]:443 ssl default_server;
      	#
      	# Note: You should disable gzip for SSL traffic.
      	# See: https://bugs.debian.org/773332
      	#
      	# Read up on ssl_ciphers to ensure a secure configuration.
      	# See: https://bugs.debian.org/765782
      	#
      	# Self signed certs generated by the ssl-cert package
      	# Don't use them in a production server!
      	#
      	# include snippets/snakeoil.conf;
      
      	root /var/www/qq.com/;
      
      	# Add index.php to the list if you are using PHP
      	index.php index index.html index.htm index.nginx-debian.html ;	# 将php增加到起始页面中
      
      	server_name www.qq.com;
      
      	location / {
      		# First attempt to serve request as file, then
      		# as directory, then fall back to displaying a 404.
      		try_files $uri $uri/ =404;
      	}
      
      	# 下面一段表示接收到php文件访问时,做出什么操作,这里配置为接收到php资源请求时将请求转移给php-fpm来进行处理
      	# pass PHP scripts to FastCGI server
      	#
      	location ~ \.php$ {	# 取消这行注释
      		include snippets/fastcgi-php.conf;	# 取消这行注释,让php在运行的过程中可以读取到相应的配置文件
      	#
      	#	# With php-fpm (or other unix sockets):
      		fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; # 取消这行注释,将最后的 php7.0-fpm.sock 改为本机当前运行的php进程名称php7.2-fpm.sock
      	#	# With php-cgi (or other tcp sockets):
      	#	fastcgi_pass 127.0.0.1:9000;
      	}	# 取消这行注释
      
      	# deny access to .htaccess files, if Apache's document root
      	# concurs with nginx's one
      	#
      	location ~ /\.ht {
      		deny all;
      	}
      }
      
      
      # Virtual Host configuration for example.com
      #
      # You can move that to a different file under sites-available/ and symlink that
      # to sites-enabled/ to enable it.
      #
      #server {
      #	listen 80;
      #	listen [::]:80;
      #
      #	server_name example.com;
      #
      #	root /var/www/example.com;
      #	index index.html;
      #
      #	location / {
      #		try_files $uri $uri/ =404;
      #	}
      #}
      

    4. 将php文件移到站点目录中去,这里简单演示一下,在站点目录/var/www/qq.com/中创建index.php文件,里面写

      <?php
          phpinfo(); 
      ?>
      
    5. 重启服务

      • 命令:sudo systemctl restart nginx.service 重启Nginx服务
      • 命令:sudo systemctl restart php7.2-fpm.service 重启php-fpm服务
    6. 浏览器打开访问站点即可

  • PHP简单配置

    • 命令:sudo vim /etc/php/7.2/fpm/php.ini 编辑PHP的主配置文件,修改其中的

      cgi.fix_pathinfo=0	;将这一项改成0,出于安全的考虑,强烈建议
      
      ;上传文件,如果不需要建议关闭
      file_uploads = On	;允许上传改为On,不允许上传改为Off
      upload_max_filesize = 2M	;修改单个上传文件的最大大小
      
      allow_url_fopen = On	;是否允许站点包含站点以外的url地址,不需要建议关闭
      allow_url_include = Off	;是否允许站点包含本地文件,不需要建议关闭
      
      memory_limit = 128M	;设置PHP程序可以用内存的大小,最小建议就128M,最大视应用
      程序具体情况而定
      
    • 然后重启php-fpm服务使配置生效,命令:sudo systemctl restart php7.2-fpm.service

10.4.6 让Nginx支持SSL {#10.4.6 让Nginx支持SSL_1}

  1. 生成SSL证书

    • 商业证书颁发机构,[参考链接](#10.2.6 证书_1)
  • 生成自签名证书,[参考链接](#10.2.5 配置https_1)
  1. 编辑站点配置文件

    ##
    # You should look at the following URL's in order to grasp a solid understanding
    # of Nginx configuration files in order to fully unleash the power of Nginx.
    # https://www.nginx.com/resources/wiki/start/
    # https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
    # https://wiki.debian.org/Nginx/DirectoryStructure
    #
    # In most cases, administrators will remove this file from sites-enabled/ and
    # leave it as reference inside of sites-available where it will continue to be
    # updated by the nginx packaging team.
    #
    # This file will automatically load configuration files provided by other
    # applications, such as Drupal or Wordpress. These applications will be made
    # available underneath a path with that package name, such as /drupal8.
    #
    # Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
    ##
    
    # Default server configuration
    #
    server {
    	listen 443 ssl;	# 修改端口为443,并在后面添加ssl,说明ssl使用在这个端口上,也可以绑定其他端口,但是如果想让访问者通过https直接方法的话就写443,因为这是https的默认端口
    
    	ssl_certificate /etc/ssl/certs/qq.com;	# 指定证书位置
    	ssl_certificate_key /etc/ssl/private/qq.key;	# 指定key(秘钥)文件位置
    
    	# SSL configuration
    	#
    	# listen 443 ssl default_server;
    	# listen [::]:443 ssl default_server;
    	#
    	# Note: You should disable gzip for SSL traffic.
    	# See: https://bugs.debian.org/773332
    	#
    	# Read up on ssl_ciphers to ensure a secure configuration.
    	# See: https://bugs.debian.org/765782
    	#
    	# Self signed certs generated by the ssl-cert package
    	# Don't use them in a production server!
    	#
    	# include snippets/snakeoil.conf;
    
    	root /var/www/qq.com/;
    
    	# Add index.php to the list if you are using PHP
    	index index.php index.html index.htm index.nginx-debian.html;
    
    	server_name www.qq.com;
    
    	location / {
    		# First attempt to serve request as file, then
    		# as directory, then fall back to displaying a 404.
    		try_files $uri $uri/ =404;
    	}
    
    	# pass PHP scripts to FastCGI server
    	#
    	location ~ \.php$ {
    		include snippets/fastcgi-php.conf;
    	#
    	#	# With php-fpm (or other unix sockets):
    		fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    	#	# With php-cgi (or other tcp sockets):
    	#	fastcgi_pass 127.0.0.1:9000;
    	}
    
    	# deny access to .htaccess files, if Apache's document root
    	# concurs with nginx's one
    	#
    	location ~ /\.ht {
    		deny all;
    	}
    }
    
    
    # Virtual Host configuration for example.com
    #
    # You can move that to a different file under sites-available/ and symlink that
    # to sites-enabled/ to enable it.
    #
    #server {
    #	listen 80;
    #	listen [::]:80;
    #
    #	server_name example.com;
    #
    #	root /var/www/example.com;
    #	index index.html;
    #
    #	location / {
    #		try_files $uri $uri/ =404;
    #	}
    #}
    
  2. 命令:sudo systemctl restart nginx.service 重启Nginx服务

10.4.7 安装Let's encrypt证书 {#1047-安装lets-encrypt证书}

  1. 命令:sudo apt update && sudo apt install certbot python-certbot-nginx 安装客户端程序
  2. 命令:sudo certbot --nginx -m admin@lab.com -d www.lab.com -d lab.com 申请证书
    • -m指定联系邮箱
    • -d指定域名,可指定多个
  3. 得到的证书存放在 /etc/letsencrypt/live/目录下
  4. 证书有效期是90天,到期后进行证书更新,命令:sudo certbot renew --dry-run
  5. 测试SSL是否成功,访问SSL扫描工具,用来扫描自己的网站看看有什么问题

10.4.8 反向代理 {#1048-反向代理}

  • 简介

    • Apache 不适合用于高并发、高负载环境
    • Nginx没有内建支持动态内容处理能力
    • 结合 Apache / Nginx 的优势
      • Nginx接受入站请求和静态内容缓存,动态请求发送给Apache,Apache完成动态内容处理
      • Nginx作为反向代理(动态请求转发给Apache)
    • 代理
      • 代理客户端访问外网服务器
    • 反向代理
      • 代理服务器对外提供服务,接受客户端请求
      • 安全层过滤客户端恶意请求(云waf)
    • Nginx可以做http,ftp,smtp,邮件相关协议的代理等,甚至可以做最原始的TCP协议的代理
  • 使用场景假设

    • 将访问php动态页面资源的请求转发给Apache
    • 其余静态资源,如图片,html页面等静态资源直接让Nginx处理掉
  • 场景一:一台机器,Nginx反向代理,Nginx与Apache结合使用步骤 {#10.4.8 反向代理_1}

    1. 命令:sudo apt install apache2 安装Apache

    2. Apache安装完毕之后,编辑**/etc/apache2/目录下的ports.conf**配置文件,将Apache默认监听的80端口和443端口改为其他端口(例如改为8080和8443),因为两个web服务器都默认监听80和443端口会产生冲突,而Nginx是接受入站请求的所以让他使用默认的端口,方便访问

    3. 再修改Apche默认站点监听的端口,编辑**/etc/apache2/sites-available/目录下的000-default.conf**,将默认监听的80端口改为其他(比如8080)

    4. 让Apache支持PHP,[点这里](#10.2.7 让Apache支持PHP_1)

    5. 编辑**/etc/apache2/mods-available/目录下的 dir.conf配置文件,将index.php**加入到主页的第一个索引中(可选操作,不加可以手动访问php文件)

    6. 在Apache配置的站点目录中放置或创建PHP文件,这里简单演示,在/var/www/html/目录下创建index.php文件,内容写

      <?php
      	phpinfo();
      ?>
      
    7. 命令:sudo systemctrl restart apache2.service 配置完成之后重启Apche服务

    8. 命令:sudo apt install nginx 安装Nginx

    9. 安装好Nginx之后,编辑**/etc/nginx/sites-available/目录下的default**默认站点配置文件,设置php动态页面资源请求的转发

      ##
      # You should look at the following URL's in order to grasp a solid understanding
      # of Nginx configuration files in order to fully unleash the power of Nginx.
      # https://www.nginx.com/resources/wiki/start/
      # https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
      # https://wiki.debian.org/Nginx/DirectoryStructure
      #
      # In most cases, administrators will remove this file from sites-enabled/ and
      # leave it as reference inside of sites-available where it will continue to be
      # updated by the nginx packaging team.
      #
      # This file will automatically load configuration files provided by other
      # applications, such as Drupal or Wordpress. These applications will be made
      # available underneath a path with that package name, such as /drupal8.
      #
      # Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
      ##
      
      # Default server configuration
      #
      server {
      	listen 80 default_server;
      	listen [::]:80 default_server;
      
      	# SSL configuration
      	#
      	# listen 443 ssl default_server;
      	# listen [::]:443 ssl default_server;
      	#
      	# Note: You should disable gzip for SSL traffic.
      	# See: https://bugs.debian.org/773332
      	#
      	# Read up on ssl_ciphers to ensure a secure configuration.
      	# See: https://bugs.debian.org/765782
      	#
      	# Self signed certs generated by the ssl-cert package
      	# Don't use them in a production server!
      	#
      	# include snippets/snakeoil.conf;
      
      	root /var/www/html;
      
      	# Add index.php to the list if you are using PHP
      	index index.html index.htm index.nginx-debian.html;
      
      	server_name _;
      
      	location / {
      		# First attempt to serve request as file, then
      		# as directory, then fall back to displaying a 404.
      		try_files $uri $uri/ =404;
      	}
      
      	# 设置php动态资源请求转发
      	# pass PHP scripts to FastCGI server
      	#
      	location ~ \.php$ {	# 访问php资源文件时的处理
      	#	include snippets/fastcgi-php.conf;
      		proxy_pass http://127.0.0.1:8080;	# 设置只要收到php资源请求就转发给本机的8080端口
      		proxy_set_header X-Real-IP $remote_addr;	# 设置转发头,将真实请求的IP发送给Apache,否则在Apache看来所有的请求都是来自于本机的Nginx
      		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;	# 不是标准规定的头部,但是通常会被用来代理链过程中每一跳的IP地址
      		proxy_set_header Host $host;	# 主机头
      		proxy_set_header X-Forwarded-Proto $scheme;	# 让Nginx自动提取使用的是什么协议并赋值给scheme变量
      
      	#	# With php-fpm (or other unix sockets):
      	#	fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
      	#	# With php-cgi (or other tcp sockets):
      	#	fastcgi_pass 127.0.0.1:9000;
      	}
      
      	# 新增配置,将静态资源留给Nginx自己处理
      	location ~* \.(js|css|jpg|png|svg|html|htm) {	# 自己定义什么类型的静态资源在本地缓存一份,这样可以提高访问速度
      		expires 10d;	# 表示Nginx缓存的日期,这里设置为10天过期
      	}
      	# deny access to .htaccess files, if Apache's document root
      	# concurs with nginx's one
      	#
      	#location ~ /\.ht {
      	#	deny all;
      	#}
      }
      
      
      # Virtual Host configuration for example.com
      #
      # You can move that to a different file under sites-available/ and symlink that
      # to sites-enabled/ to enable it.
      #
      #server {
      #	listen 80;
      #	listen [::]:80;
      #
      #	server_name example.com;
      #
      #	root /var/www/example.com;
      #	index index.html;
      #
      #	location / {
      #		try_files $uri $uri/ =404;
      #	}
      #}
      
    10. 使用浏览器访问php文件使用80端口,查看结果

  • 场景二:三台机器,第一、二台安装Nginx,第三台安装Apache,用户向第一台Nginx请求php资源文件,第一台Nginx转发给第二台Nginx,第二台最后再转发给第三台的Apache服务器由Apache服务器来处理这个php资源请求,最终实现Nginx的链式代理(本次演示不区分静态资源和PHP资源,将所有的请求都转发给第三台机器的Apache,怎么区分请看[场景一](#10.4.8 反向代理_1))

    1. 第一台配置Nginx的机器的ip是192.168.2.107,第二台配置Nginx的机器ip是192.168.2.220,第三台配置Apache的机器是192.168.2.247

    2. 先对第一台配置Nginx机器进行操作,192.168.2.107

      1. 命令:sudo vim /etc/nginx/sites-available/default 编辑站点配置文件,并保存

        ##
        # You should look at the following URL's in order to grasp a solid understanding
        # of Nginx configuration files in order to fully unleash the power of Nginx.
        # https://www.nginx.com/resources/wiki/start/
        # https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
        # https://wiki.debian.org/Nginx/DirectoryStructure
        #
        # In most cases, administrators will remove this file from sites-enabled/ and
        # leave it as reference inside of sites-available where it will continue to be
        # updated by the nginx packaging team.
        #
        # This file will automatically load configuration files provided by other
        # applications, such as Drupal or Wordpress. These applications will be made
        # available underneath a path with that package name, such as /drupal8.
        #
        # Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
        ##
        
        # Default server configuration
        #
        server {
        	listen 80 default_server;
        	listen [::]:80 default_server;
        
        	# SSL configuration
        	#
        	# listen 443 ssl default_server;
        	# listen [::]:443 ssl default_server;
        	#
        	# Note: You should disable gzip for SSL traffic.
        	# See: https://bugs.debian.org/773332
        	#
        	# Read up on ssl_ciphers to ensure a secure configuration.
        	# See: https://bugs.debian.org/765782
        	#
        	# Self signed certs generated by the ssl-cert package
        	# Don't use them in a production server!
        	#
        	# include snippets/snakeoil.conf;
        
        	root /var/www/html;
        
        	# Add index.php to the list if you are using PHP
        	index index.html index.htm index.nginx-debian.html;
        
        	server_name _;
        
        	# 配置所有的请求都发送给第二台机器上的Nginx
        	location / {
        		# First attempt to serve request as file, then
        		# as directory, then fall back to displaying a 404.
        		try_files $uri $uri/ =404;
        
        		proxy_pass http://192.168.2.220;	# 配置代理,发送给192.168.2.220机器的80端口
        	}
        
        	# pass PHP scripts to FastCGI server
        	#
        	#location ~ \.php$ {
        	#	include snippets/fastcgi-php.conf;
        	#
        	#	# With php-fpm (or other unix sockets):
        	#	fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        	#	# With php-cgi (or other tcp sockets):
        	#	fastcgi_pass 127.0.0.1:9000;
        	#}
        
        	# deny access to .htaccess files, if Apache's document root
        	# concurs with nginx's one
        	#
        	#location ~ /\.ht {
        	#	deny all;
        	#}
        }
        
        
        # Virtual Host configuration for example.com
        #
        # You can move that to a different file under sites-available/ and symlink that
        # to sites-enabled/ to enable it.
        #
        #server {
        #	listen 80;
        #	listen [::]:80;
        #
        #	server_name example.com;
        #
        #	root /var/www/example.com;
        #	index index.html;
        #
        #	location / {
        #		try_files $uri $uri/ =404;
        #	}
        #}
        
      2. 命令:sudo systemctl restart nginx.service 重启Nginx服务,使改过的配置生效

    3. 再对第二台配置Nginx机器进行操作,192.168.2.220

      1. 修改**/var/www/html/index.nginx-debian.html**默认首页,修改其中内容,以示区别,否则第一台和第二台Nginx都展示的默认的欢迎页看不出区别,所有就分辨不出第一台反向代理有没有设置成功

      2. 命令:sudo vim /etc/nginx/sites-available/default 编辑站点配置文件,并保存

        ##
        # You should look at the following URL's in order to grasp a solid understanding
        # of Nginx configuration files in order to fully unleash the power of Nginx.
        # https://www.nginx.com/resources/wiki/start/
        # https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
        # https://wiki.debian.org/Nginx/DirectoryStructure
        #
        # In most cases, administrators will remove this file from sites-enabled/ and
        # leave it as reference inside of sites-available where it will continue to be
        # updated by the nginx packaging team.
        #
        # This file will automatically load configuration files provided by other
        # applications, such as Drupal or Wordpress. These applications will be made
        # available underneath a path with that package name, such as /drupal8.
        #
        # Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
        ##
        
        # Default server configuration
        #
        server {
        	listen 80 default_server;
        	listen [::]:80 default_server;
        
        	# SSL configuration
        	#
        	# listen 443 ssl default_server;
        	# listen [::]:443 ssl default_server;
        	#
        	# Note: You should disable gzip for SSL traffic.
        	# See: https://bugs.debian.org/773332
        	#
        	# Read up on ssl_ciphers to ensure a secure configuration.
        	# See: https://bugs.debian.org/765782
        	#
        	# Self signed certs generated by the ssl-cert package
        	# Don't use them in a production server!
        	#
        	# include snippets/snakeoil.conf;
        
        	root /var/www/html;
        
        	# Add index.php to the list if you are using PHP
        	index index.html index.htm index.nginx-debian.html;
        
        	server_name _;
        
        	# 配置所有的请求都发送给第三台机器上的Apache
        	location / {
        		# First attempt to serve request as file, then
        		# as directory, then fall back to displaying a 404.
        		try_files $uri $uri/ =404;
        
        		proxy_pass http://192.168.2.247;	# 配置代理,发送给192.168.2.247机器的80端口
        	}
        
        	# pass PHP scripts to FastCGI server
        	#
        	#location ~ \.php$ {
        	#	include snippets/fastcgi-php.conf;
        	#
        	#	# With php-fpm (or other unix sockets):
        	#	fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        	#	# With php-cgi (or other tcp sockets):
        	#	fastcgi_pass 127.0.0.1:9000;
        	#}
        
        	# deny access to .htaccess files, if Apache's document root
        	# concurs with nginx's one
        	#
        	#location ~ /\.ht {
        	#	deny all;
        	#}
        }
        
        
        # Virtual Host configuration for example.com
        #
        # You can move that to a different file under sites-available/ and symlink that
        # to sites-enabled/ to enable it.
        #
        #server {
        #	listen 80;
        #	listen [::]:80;
        #
        #	server_name example.com;
        #
        #	root /var/www/example.com;
        #	index index.html;
        #
        #	location / {
        #		try_files $uri $uri/ =404;
        #	}
        #}
        
      3. 命令:sudo systemctl restart nginx.service 重启Nginx服务,使改过的配置生效

    4. 打开浏览器,访问第一台机器或第二台机器,最终显示的都是Apache的欢迎页,即配置成功

10.4.9 负载均衡 {#1049-负载均衡}

  • 基于反向代理实现负载均衡,比如:在最前面放上Nginx服务器,让Nginx反向代理一台Apache服务器一台Nginx服务器,当有大量访问来时,Nginx通过一定的算法将访问分配给后面的Apache或Nginx服务器(平均分配,按权重分配或者哪台服务器性能高多分配一点),实现负载均衡

  • 场景:三台机器,第一、二台安装Nginx,第三台安装Apache,用户向第一台Nginx请求,第一台Nginx转发给第二台Nginx服务器或者第三台Apache服务器,实现负载均衡

    1. 第一台配置Nginx的机器的ip是192.168.2.107,第二台配置Nginx的机器ip是192.168.2.220,第三台配置Apache的机器是192.168.2.247

    2. 先修改三台机器的默认首页为不同内容,好区分

    3. 对第一台接收外部请求的Nginx进行操作

      1. 命令:sudo vim /etc/nginx/sites-available/default 编辑站点配置文件,并保存

        ##
        # You should look at the following URL's in order to grasp a solid understanding
        # of Nginx configuration files in order to fully unleash the power of Nginx.
        # https://www.nginx.com/resources/wiki/start/
        # https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
        # https://wiki.debian.org/Nginx/DirectoryStructure
        #
        # In most cases, administrators will remove this file from sites-enabled/ and
        # leave it as reference inside of sites-available where it will continue to be
        # updated by the nginx packaging team.
        #
        # This file will automatically load configuration files provided by other
        # applications, such as Drupal or Wordpress. These applications will be made
        # available underneath a path with that package name, such as /drupal8.
        #
        # Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
        ##
        
        # Default server configuration
        # 定义一个服务器组,需要在server定义段上面定义,这个服务器组就是要转发请求的目标
        upstream srvs {	# srv是服务器组名称,可以自己任意命名
        	least_conn;	# 设置负载均衡的方法,谁响应快就把下一个请求转发给谁
        	server 192.168.2.220 weight=1;	# 权重设为1
        	server 192.168.2.247 weight=2	# 权重设为2
        	# 权重,如果访问了三次,一次访问转发给192.168.2.220,两次访问转发给192.168.2.247
        }
        #
        server {
        	listen 80 default_server;
        	listen [::]:80 default_server;
        
        	# SSL configuration
        	#
        	# listen 443 ssl default_server;
        	# listen [::]:443 ssl default_server;
        	#
        	# Note: You should disable gzip for SSL traffic.
        	# See: https://bugs.debian.org/773332
        	#
        	# Read up on ssl_ciphers to ensure a secure configuration.
        	# See: https://bugs.debian.org/765782
        	#
        	# Self signed certs generated by the ssl-cert package
        	# Don't use them in a production server!
        	#
        	# include snippets/snakeoil.conf;
        
        	root /var/www/html;
        
        	# Add index.php to the list if you are using PHP
        	index index.html index.htm index.nginx-debian.html;
        
        	server_name _;
        
        	# 配置所有的请求都发送给服务器组中的服务器,按照定义的权重比例进行转发
        	location / {
        		# First attempt to serve request as file, then
        		# as directory, then fall back to displaying a 404.
        		try_files $uri $uri/ =404;
        
        		proxy_pass http://srvs;
        
        	}
        
        	# pass PHP scripts to FastCGI server
        	#
        	#location ~ \.php$ {
        	#	include snippets/fastcgi-php.conf;
        	#
        	#	# With php-fpm (or other unix sockets):
        	#	fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        	#	# With php-cgi (or other tcp sockets):
        	#	fastcgi_pass 127.0.0.1:9000;
        	#}
        
        	# deny access to .htaccess files, if Apache's document root
        	# concurs with nginx's one
        	#
        	#location ~ /\.ht {
        	#	deny all;
        	#}
        }
        
        
        # Virtual Host configuration for example.com
        #
        # You can move that to a different file under sites-available/ and symlink that
        # to sites-enabled/ to enable it.
        #
        #server {
        #	listen 80;
        #	listen [::]:80;
        #
        #	server_name example.com;
        #
        #	root /var/www/example.com;
        #	index index.html;
        #
        #	location / {
        #		try_files $uri $uri/ =404;
        #	}
        #}
        
      2. 命令:sudo systemctl restart nginx.service 重启Nginx服务,使改过的配置生效

    4. 打开浏览器,访问第一台Nginx会发现按权重(或其他负载均衡方法)将访问转发给后面的Apache或Nginx服务器

  • 负载均衡的方法

    | 方法 | 解释 | |-------------|--------------------------------------------| | round-robin | 轮训(默认),按照配置的比例你几次再我几次轮流这样 | | least_conn | 最少连接数优先,谁的连接数少就转发给谁 | | least_time | 响应速度优先,谁的响应速度最快就把下一个请求发给谁 | | hash | 基于请求的HASH值,相同的HASH都转发给同一个服务器 | | ip_hash | 基于IP地址的HASH值,同意IP地址每次访问相同的服务器,适用于需要会话保持的应用 |

10.5 Tomcat {#105-tomcat}

10.5.1 概述 {#1051-概述}

  • Tomcat是由Apache组织开发的一个Servlet容器
    • 实现对servlet、JSP、JAVASocket等支持
    • 包含HTTP服务器
    • 作为中间件使用
    • 可与Nginx结合使用

10.5.2 安装JAVA环境 {#1052-安装java环境}

  • Oracle的JDK

    1. 命令:sudo add-apt-repository ppa:linuxuprising/java 添加库
    2. 命令:sudo apt update
    3. 命令:sudo apt install oracle-java12-installer oracle-java12-set-default 安装java12并将oracle的java设置为操作系统默认的java运行环境
    4. 命令:source /etc/profile
  • openJDK

    • 方式一 命令:sudo apt install default-jdk 安装Ubuntu官方默认的JDK,是openJDK
    • 方式二 命令:sudo apt install openjdk-11-jdk 安装openJDK的11版本,更改其中的数字11安装不同版本的openJDK
  • 配置系统默认用哪个JAVA,假设openJDK和Oracle JDK在Ubuntu上都安装了

    • 命令:sudo update-alternatives --config java 执行命令之后,会给出让你选择的那个JAVA的提示,填写自己想使用的JAVA即可
    • 或者想使用Oracle JDK,那么就把其他的JDK卸载掉即可

10.5.3 安装 {#1053-安装}

  • Ubuntu官方库安装

    1. 命令:sudo apt install tomcat8 安装tomcat

    2. 可选安装

      • 命令:sudo apt install tomcat8-docs 安装tomcat文档

      • 命令:sudo apt install tomcat8-admin 安装tomcat基于web界面功能管理的软件包

      • 命令:sudo apt install tomcat8-examples 一些tomcat的例子

    3. 安装JDK环境,命令:sudo apt install default-jdk 这里安装openJDK,你可以自己选择安装Oracle的JDK

  • 手动安装(Ubuntu官方库可能没有自己想要的Tomcat版本)

    1. 安装JDK环境,命令:sudo apt install default-jdk 这里安装openJDK,你可以自己选择安装Oracle的JDK

    2. 命令:sudo useradd -m -U -d /opt/tomcat -s /bin/false tomcat 创建一个叫tomcat 的账号(自己随便取)来给Tomcat服务器来运行,指定账号主目录是**/opt/tomcat**,/bin/false表示禁用shell登录权限

    3. 去Tomcat官方下载Tomcat软件包链接,使用wget或其他方式将Tomcat下载下来,例如

    4. 解压下载好的文件,将解压后的到的目录移动到tomcat账号的主目录下(这里是**/opt/tomcat**)

    5. 命令:sudo chown -R tomcat: /opt/tomcat 修改tomcat账号主目录下的目录及文件属主和属组都为tomcat账号和组

    6. 命令:sudo chmod +x /opt/tomcat/apache-tomcat-8.5.43/bin/*.sh 给sh脚本文件赋予可执行权限

    7. 命令:sudo ln -s /opt/tomcat/apache-tomcat-8.5.43/ /opt/tomcat/latest 给Tomcat软件目录做一个符号链接,让latest目录连接到Tomcat软件目录上,后面的配置中写latest目录,执行Tomcat运行的目录是在/opt/tomcat/latest这个目录下,这样的做的好处是,当有Tomcat版本更新的时候只需要再将/opt/tomcat/latest目录链接上去,配置中配置的Tomcat运行目录(也就是latest目录)不需要改变,节省日常维护成本 ,否则每次Tomcat更新都要重新写配置文件,这样不仅麻烦还容易改错,从而出现问题,再执行命令:sudo chown -R tomcat: /opt/tomcat/latest 将创建的latest链接所有者所有组都改为tomcat账号

    8. 命令:sudo vim /etc/systemd/system/tomcat.service 创建Tomcat的服务,里面写

      [Unit]
      Description=Tomcat 8.5 servlet container	# 描述信息
      After=network.target
      
      [Service]
      Type=forking
      User=tomcat		# 指定使用哪个账号来启动
      Group=tomcat	# 指定使用哪个组来启动
      Environment="JAVA_HOME=/usr/lib/jvm/default-java"	# 配置环境变量,指定JVM所在的目录
      Environment="JAVA_OPTS=-Djava.security.egd=file:///dev/urandom"	# 
      Environment="CATALINA_BASE=/opt/tomcat/latest"
      Environment="CATALINA_HOME=/opt/tomcat/latest"
      Environment="CATALINA_PID=/opt/tomcat/latest/temp/tomcat.pid"
      Environment="CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC"
      # 下面指定的脚本都是刚刚创建的符号链接latest目录下的,若指定Tomcat所在的真正目录,则每次选择手动安装Tomcat更新时都要在此处更改脚本所在的目录,增加维护的成本
      ExecStart=/opt/tomcat/latest/bin/startup.sh		# 指定启动运行的脚本
      ExecStop=/opt/tomcat/latest/bin/shutdown.sh		# 指定结束运行的脚本
      
      [Install]
      WantedBy=multi-user.target
      

      命令:sudo systemctl daemon-reload 让systemctl的配置文件重新加载一下,因为刚刚手动加了一个tomcat.service文件,reload一下让systemctl知道新增了一个.service服务

10.5.4 WEB接口管理 {#1054-web接口管理}

  • 设置管理员IP可以远程访问Tomcat的WEB管理页面,默认情况下只能在安装Tomcat本机上访问

  • 设置步骤

    1. 命令:sudo vim /opt/tomcat/latest/conf/tomcat-users.xml 编辑配置文件,在配置文件中添加角色和用户以便远程来进行登陆(注意/opt/tomcat目录是上一节手动安装Tomcat时创建的tomcat账号的主目录并将Tomcat软件放入到此目录中了,latest目录是上一节手动安装Tomcat时将Tomcat软件包创建的符号链接)

      <!--
      	在此xml配置文件中的 <tomcat-users> 标签中添加如下内容
      -->
      <role rolename="admin-gui" />	<!--定义admin-gui角色-->
      <role rolename="manager-gui" />	<!--定义manager-gui角色-->
      <!--定义用户,用户名是admin,密码是pass,指定角色为admin-gui和manager-gui,这样这个用户就拥有了这两个角色的全部权限-->
      <user username="admin" password="pass" roles="admin-gui,manager-gui" />
      
    2. 命令:sudo vim /opt/tomcat/latest/webapps/manager/META-INF/context.xml 编辑配置文件,添加管理员IP地址允许远程访问Tomcat Web管理界面

      命令:sudo vim /opt/tomcat/latest/webapps/manager/META-INF/context.xml 编辑配置文件,添加管理员IP地址允许远程访问Tomcat Web管理界面

      上面两条命令的修改方式都是相同的,方式见下图

    3. 命令:sudo systemctl restart tomcat.service 重启Tomcat服务,使配置生效

第 11 章 数据库服务 {#第-11-章-数据库服务}

11.1 数据库管理系统 {#111-数据库管理系统}

11.1.1 概述 {#1111-概述}

  • 数据是应用的核心
  • 按照结构组织、存储和管理数据的仓库
  • 可视化电子化的文件柜(增删改查)
  • 数据挖掘透视表象背后的真相
  • 数据比人更了解人
  • 人工智能更依赖于数据

11.1.2 数据库的分类 {#1112-数据库的分类}

  • 关系型数据库
    • 库、表、字段、记录
    • 使用结构化查询语言 SQL(Structured Query Language)
  • 非关系型数据库 NoSQL
    • 大数据技术的发展暴露关系型数据库的问题
    • NoSQL为分布式大规模存储而设计
    • 存储不同格式的数据类型(文件型数据)
    • 图形数据库、文档数据库、键值对数据库、一张表可以很大
  • NoSQL并非取代SQL,而是互相补强
  • Flat file DB,一个文件按一定格式存储,也叫一个数据库
    • 例如:/etc/passwd 以分割定界符定义数据结构
    • 使用范围小 ,应用需要理解数据结构

11.1.3 数据库管理系统(DBMS) {#1113-数据库管理系统dbms}

  • Database Management System(DBMS)

  • 操纵和管理数据库的软件

  • 功能作用

    | 作用 | 解释 | |-------|--------------------------| | 数据定义 | 定义数据结构,及完整性机密性约束 | | 数据操作 | 实现对数据操作 | | 运行管理 | 多用户、安全性、存取限制、事务管理、自动恢复 | | 组织与存储 | 分类管理各种数据(数据字典、用户数据、存取路径) | | 数据保护 | 恢复、并发控制、完整性、机密性 | | 数据库维护 | 数据载入、转换、存储、重组重构、性能监控等 | | 通信 | OS接口、网络通信、服务器间相互操作 |

11.2 MySQL数据库 {#112-mysql数据库}

11.2.1概述 {#1121概述}

  • 2009年Oracle收购Sun Microsystems(MySQL所有者)
  • 成熟的开源DBMS(满足大数据集应用需要)
  • 为避免开源被商业所弱化和扼杀分叉出MariaDB
  • 很多Linux发行版已弃用MySQL(转而采用MariaDB)
  • 支持多种存储引擎
    • MylSAM
    • innoDB
    • 内存中存储

11.2.2 安装 {#1122-安装}

  • 命令:sudo apt install mysql-server 安装mysql

11.2.3 安全配置(必要) {#1123-安全配置必要}

  1. 命令:sudo mysql_secure_installation 配置root账户密码及对mysql安装的文件进行安全的加固,设置,这是安装完毕之后必须要做的事情

    ➜  ~ sudo mysql_secure_installation 	# 执行安全配置命令
    
    Securing the MySQL server deployment.
    
    Connecting to MySQL using a blank password.
    
    VALIDATE PASSWORD PLUGIN can be used to test passwords
    and improve security. It checks the strength of password
    and allows the users to set only those passwords which are
    secure enough. Would you like to setup VALIDATE PASSWORD plugin?
    
    Press y|Y for Yes, any other key for No: y	# 是否要给root账号设置密码,输y
    
    There are three levels of password validation policy:
    
    LOW    Length >= 8
    MEDIUM Length >= 8, numeric, mixed case, and special characters
    STRONG Length >= 8, numeric, mixed case, special characters and dictionary                  file
    
    Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 2	# 输入密码的等级,2表示STRONG
    Please set the password for root here.
    
    New password: 						# 输入密码
    
    Re-enter new password: 				# 再次输入密码
    
    Estimated strength of the password: 90 	# 给你的密码打打分
    Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : y	# 问你看完打分之后,是否还要使用输入的密码
    By default, a MySQL installation has an anonymous user,
    allowing anyone to log into MySQL without having to have
    a user account created for them. This is intended only for
    testing, and to make the installation go a bit smoother.
    You should remove them before moving into a production
    environment.
    
    Remove anonymous users? (Press y|Y for Yes, any other key for No) : y	# 是否移除安装过程中自动创建的 anonymous 账号
    Success.
    
    
    Normally, root should only be allowed to connect from
    'localhost'. This ensures that someone cannot guess at
    the root password from the network.
    
    Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y	# 是否禁止root用户远程登录
    Success.
    
    By default, MySQL comes with a database named 'test' that
    anyone can access. This is also intended only for testing,
    and should be removed before moving into a production
    environment.
    
    
    Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y	# 是否移除安装过程中自动创建的 test 数据库
     - Dropping test database...
    Success.
    
     - Removing privileges on test database...
    Success.
    
    Reloading the privilege tables will ensure that all changes
    made so far will take effect immediately.
    
    Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y	# 是否重新加载权限表,让配置生效
    Success.
    
    All done! 
    
    
  2. 配置完成之后使用mysql客户端程序登录mysql服务器,在执行:sudo apt install mysql-server安装mysql服务时也同时安装了mysql的客户端程序,这个客户端程序的命令就叫:mysql

  3. 第一次登陆mysql ,使用命令:sudo mysql,以mysql数据库root账号登录 ,如果单独执行mysql这条命令,就会以当前系统登录用户名相同的名字来登录mysql数据库(系统用户名和mysql数据库用户名是两个不相关的东西,只是登录mysql时不指定用户名就以系统登录的用户名来登录mysql),因为Linux系统和MySQL数据库中权限最高的账号都是root,执行sudo mysql时,命令前用了sudo是以Ubuntu系统的root账号来执行mysql命令的,所以mysql客户端就以root账号来登录数据库

  4. 执行完sudo mysql 命令之后,发现直接就登入了mysql数据库,并没有要输入第一步执行的sudo mysql_secure_installation 命令中设置的root账号密码,原因是mysql数据库中root用户的认证方式是auth_socket不是密码认证方式,不过还是建议设置成密码认证方式

  5. 将root用户的身份认证方式修改为密码方式认证,并同时设置一个密码,最后刷新配置时设置生效

  6. 修改身份认证方式完毕之后下次再登陆mysql时需要使用命令:mysql -u root -p ,来进行登陆,-u指定登录用户名,-p指定密码 ,不可以再使用sudo mysql来进行登陆了

11.2.4 创建账号 {#1124-创建账号}

  • 创建本地登录账号

    1. 在mysql命令行中执行:create user 'study'@'localhost' identified by '12345678';
      • 创建了study账号,并设置只能在本机(localhost)上登陆此账号,并指定密码为12345678

    2. 给新创建的账号赋予权限

  • 创建可以通过网络访问的账号

    • 第一种方式,先创建账号再赋予权限

      1. 在mysql命令行中执行:create user 'study'@'%' identified by '12345678';
      • % 表示允许所有这个账号允许所有ip来连接
    1. 然后给新创建打的study账号赋予权限
    • 第二种方式,在赋予权限的同时创建一个新账号

      1. 在mysql命令行中执行:grant all on . to 'admin'@'%' identified by '12345678' with grant option;
        • 赋予了对所有数据库数据表的全部权限,并新创建了admin账号,并允许此账号允许所有ip来连接,账号密码为12345678
  • 创建完网络账号之后的操作(必要)

    1. 修改**/etc/mysql/mysql.conf.d/mysqld.cnf**,mysql配置文件,将其中的bind-address 配置项之后的127.0.0.1改为本机真实网卡ip地址 ,因为默认监听的是127.0.0.1这个ip地址,那么就无法进行远程连接mysql服务器
      1. 修改完成之后,执行命令:sudo systemctl restart mysql.service 重启mysql服务使修改的配置生效
    • 注意事项

      • 在创建完可以通过网络访问的账号之后,mysql密码的安全等级会变成至少是MEDIUM等级 ,MEDIUM等级的密码需要:Length >= 8, numeric, mixed case, and special characters
        • 在mysql命令行中执行:select @@validate_password_policy; 来查看密码安全等级

11.2.5 赋予权限与收回 {#1125-赋予权限与收回}

  • 赋予权限

    • 在mysql命令行中执行:grant all privileges on *.* to 'study'@'localhost' with grant option;

    • 给study账号赋予管理所有数据库全部的权限

    • all --> 赋予全部的权限,按实际需求设置权限大小,mysql权限分为4个级别,分别是:

      | 权限名 | 解释 | |----------------|--------------------------------------------| | Global Level | 全局性的管理权限,作用于整个MySQL实例级别 | | Database Level | 数据库级别的权限,作用于某个指定的数据库上或者所有的数据库上 | | Table Level | 数据库对象级别的权限,作用于指定的数据库对象上(表、视图等)或 者所有的数据库对象上 | | Column Level | 列级别的权限 |

    • *.* --> 所有数据库下的所有数据表,按实际需求设置可管理的数据库和数据表,比如:单张表可以写test.user,test数据库下的user表

  • 收回权限

    • 在mysql命令行中执行:**revoke all on *.* from study@localhost; ** 收回study账号对所有数据库数据表的所有权限

11.2.6 修改密码 {#1126-修改密码}

  1. 在mysql命令行中执行:set password for 'root'@'localhost'=password('12345678'); 修改密码
  2. 在mysql命令行中执行:flush privileges; 使修改后的密码生效

11.2.7 备份和恢复 {#1127-备份和恢复}

  • 备份
# 备份整个 库、表
mysqldump -u root -p test > db_bak.sql	# 备份数据库,使用root账号将test数据库备份成db_bak.sql文件
mysqldump -u root -p test users > db_bak.sql	# 备份数据表,使用root账号将test数据库下的users备份成db_bak.sql文件
mysqldump --all-databases -u root -p all_bak.sql	# 使用root账号将所有的数据库备份成all_bak.sql文件

# 备份指定数据,例如备份users表中uname和pass两列的数据
	# 第一种备份方式
		vim q.sql	# 创建一个q.sql文件里面写 select uname,pass from users;
		mysql -u root -p test < q.sql > out.csv	# 使用test数据库执行q.sql中的SQL语句,将查询出来的结果保存到out.csv文件中
	# 第二种备份方式,mysql命令行中备份
		mysql -u root -p	# 先登录数据库
		show variables like '%secure%'	# 查询mysql系统变量包含secure的变量,记住显示出来的secure_file_priv变量后路径,这是导出备份文件的默认路径(/var/lib/mysql-files/)
		use test;	# 选中要备份的数据库
		select uname,pass from users into outfile "/var/lib/mysql-files/out.csv";	# users表中的uname和pass列的数据到/var/lib/mysql-files/out.csv中	
  • 恢复
# 恢复.sql备份的表文件
mysqladmin -u root -p create db2	# 创建db2数据库
mysql -u root -p db2 < db_bak.sql	# 在db2数据库中恢复db_bak.sql备份的数据表

# 恢复.csv备份指定数据的文件
mysql -u root -p	# 登录到mysql命令行是
use test	# 使用要在哪个数据库中恢复
load data infile '/var/lib/mysql-files/out.csv' into table users;	# 指定要恢复的csv文件路径,并恢复到users表中

11.2.8 调优工具 {#1128-调优工具}

  1. 命令:sudo apt install mysqltuner 安装调优工具
  2. 命令:mysqltuner 执行命令,根据显示的信息进行调优

11.3 SQL语句(MySQL) {#113-sql语句mysql}

11.3.1 数据定义语言 DDL {#1131-数据定义语言-ddl}

select user();			-- 查询当前登录用户
show database;			-- 查看所有的数据库
create database test;	-- 创建 test 数据库
use test;				-- 使用 test 数据库
show tables;			-- 显示使用数据库中所有的表
select database();		-- 查看当前正在使用的数据库

create table users (	-- 创建表
	id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    uname CHAR(25),
    pass CHAR(20),
    age INT(5)
);
/*
	INT(9)				数据类型为整数(长度9)
	NOT NULL			字段不能为空
	PRIMARY KEY			主键(不能包含重复数据)
	AUTO_INCREMENT		自动递增
	CHAR(25)			定长字符串(字符数/不是字节数),输入长度的不够会在后面添加空格,缺点浪费空间,优点:性能高
    VARCHAR(length)		可变成长字符串,缺点:性能低,优点:节省空间
	TEXT				最大64KB文本可变长度字符串
	DATE				日期值(年,月,日)
	TIME				时间值(时,分,秒)
	ENUM("value1","value2",...)		枚举值列表
*/

desc users;				-- 查看当前使用数据库下的users表的结构
show create table users;	-- 查看当前使用数据库下的users表的结构(包括显示存储引擎的信息,编码方式等)
show full columns from users;	-- 查看当前使用数据库下的users表的结构

drop table users;	-- 删除users表
drop database test;	-- 删除test数据库

show engines;	-- 查询支持的存储引擎
alter table users engine=MyISAM	-- 将users表的存储引擎改为MyISAM
alter table users rename user;	-- 将users表名称改为user
alter table users modify uname varchar(20);	-- 将users表中uname列数据类型改为varchar(20)
alter table users change uname username varchar(30);	-- 将users表中uname列名称改为username,并设置数据类型为varchar(30)
alter table users add tel CHAR(20) NOT NULL after pass;	-- 对users表新增tel字段设置数据类型为CHAR(20),并将新增的列放到pass列后面
alter table users drop tel;	-- 删除users表中的tel字段

13.3.2 数据操作语言DML {#1332-数据操作语言dml}

-- 插入数据
insert into users values (null,'Lw','pass1',20);	-- 插入数据,所有列
insert into users(id,uname,pass) values (null,"zhangsan","pass2");	-- 插入指定列的数据

update users set age=50 where uname='zhangsan';	-- 将users表中uname列为zhangsan的age列数值改为50

delete from users where id=5;	-- 将users表中id列为5一行记录删除

13.3.3 数据查询语言DQL {#1333-数据查询语言dql}

select * from user;	-- 查询user表中所有列的信息
select uname,pass from user;	-- 查询user表中uname和pass列的所有信息

select * from users where age=20;	-- 查询users表中age列数值等于20的所有的信息
select * from users where age>25 and age<100;	-- 查询users表中age列数值大于20且小于100的所有的信息
select * from users where age>25 and age<100 and age!=30;	-- 查询users表中age列数值大于20且小于100的且不等于30的所有的信息
select * from users where uname='Lw';	-- 查询users表中uname列为Lw的所有的信息

select * from users order by age;		-- 查询users表中所有记录并按age列正序显示
select * from users order by age desc;	-- 查询users表中所有记录并按age列倒序显示

select concat(uname,'(',pass,')') as user_pass from users;	-- 使用concat拼接信息,并给列取了个别名user_pass,例如显示 Lw(pass1)

11.4 MariaDB数据库 {#114-mariadb数据库}

11.4.0 前排提醒 {#1140-前排提醒}

  • 可参考MySQL数据库的配置和使用,两者绝大部分的操作都是相同的

11.4.1 安装 {#1141-安装}

  • 命令:sudo apt install mariadb-server

11.4.2 安全配置(必要) {#1142-安全配置必要}

  1. 命令:sudo mysql_secure_installation 配置root账户密码及对mariaDB安装的文件进行安全的加固,设置,这是安装完毕之后必须要做的事情

    NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
          SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!
    
    In order to log into MariaDB to secure it, we'll need the current
    password for the root user.  If you've just installed MariaDB, and
    you haven't set the root password yet, the password will be blank,
    so you should just press enter here.
    
    Enter current password for root (enter for none): 	# 让你输入root密码,因为是新安装的root没有设置密码,直接回车就好
    OK, successfully used password, moving on...
    
    Setting the root password ensures that nobody can log into the MariaDB
    root user without the proper authorisation.
    
    Set root password? [Y/n] Y	# 是否要设置root账号的密码
    New password: 				# 输入密码
    Re-enter new password: 		# 再次输入密码
    Password updated successfully!
    Reloading privilege tables..
     ... Success!
    
    
    By default, a MariaDB installation has an anonymous user, allowing anyone
    to log into MariaDB without having to have a user account created for
    them.  This is intended only for testing, and to make the installation
    go a bit smoother.  You should remove them before moving into a
    production environment.
    
    Remove anonymous users? [Y/n] Y		# 是否移除匿名账号
     ... Success!
    
    Normally, root should only be allowed to connect from 'localhost'.  This
    ensures that someone cannot guess at the root password from the network.
    
    Disallow root login remotely? [Y/n] Y	# 是否禁用root账号远程登录
     ... Success!
    
    By default, MariaDB comes with a database named 'test' that anyone can
    access.  This is also intended only for testing, and should be removed
    before moving into a production environment.
    
    Remove test database and access to it? [Y/n] Y	# 是否移除测试数据库
     - Dropping test database...
     ... Success!
     - Removing privileges on test database...
     ... Success!
    
    Reloading the privilege tables will ensure that all changes made so far
    will take effect immediately.
    
    Reload privilege tables now? [Y/n] Y	# 重新加载数据库权限
     ... Success!
    
    Cleaning up...
    
    All done!  If you've completed all of the above steps, your MariaDB
    installation should now be secure.
    
    Thanks for using MariaDB!
    
  2. 登录MariaDB数据库,使用命令:sudo mysql就直接以root账号登录进去了,因为默认的root账号身份认证方式不是密码方式验证

  3. 修改root账号的身份认证方式为密码方式

  4. 设置完成之后,下次登陆MariaDB就要使用命令:mysql -u root -p来进行登陆

11.4.3 配置文件 {#1143-配置文件}

  • MariaDB的主配置文件在**/etc/mysql/mariadb.conf.d/50-server.cnf**
  • 打开配置文件将其中的bind-address后的127.0.0.1 修改为0.0.0.0,这样MariaDB就会在本机的所有物理网卡上侦听3306端口,就可以通过远程访问了
  • 更多配置内容请参考MySQL章节

11.4.4 主备服务器 {#1144-主备服务器}

  • 概述

    • 复制Replication (Replication单词意思表示主备服务器直接的复制)
      • Master --> Slave 将主服务器上数据库内容复制到Slave服务器
      • 可以限定 所有库,指定库、表进行复制到Slave
    • 复制原理
      • bin-log 二进制日志,默认是关闭的,因为占用更多的存储空间吗,如果要实现Replication那么就开启bin-log功能
      • 所有DB事件写入bin-log,例如什么时候插入了数据,什么时候删除了数据
      • 配置Slave服务器有权限读取Master中bin-log,就可以实现Replication
    • 用途
      • 扩展:Slave分担Master负载,Slave可接受数据查询
      • 分析:在Slave服务器上做数据分析,从而不影响Master服务器性能,保证业务不受影响
      • 备份:作为一种数据备份手段
      • 分布:异地保存数据副本(应用访问本地库)
  • 一台Master和一台Slave服务器,操作步骤

    1. 安装两台独立的MariaDB服务器,并用导入导出方式使两台MariaDB上的数据一致

      • 在Replication前用导入导出数据库的方式保持 Master / Slave数据一致,就比如已经有一台MariaDB已经运行一段时间了,其中已经有一些数据,现在业务扩大了要将之前的作为Master服务器,再给它配一个Slave服务器,但是新安装的Slave服务器中没有以前的数据,且Master未配置前没有开启bin-log功能,所以要使用导入导出功能将Master上已存在的数据导入到新安装Slave服务器上
      • 在执行Master导出之前,先锁定库,禁止写入(但可以读数据),防止还未将数据导入到Slave上在Master上又产生了新数据,在Master上的MariaDB命令行执行:flush tables with read lock;
    2. Master上,命令:sudo vim /etc/mysql/conf.d/mysql.cnf 编辑Master服务器上的配置文件,在其中添加配置内容,配置完成后的内容是

      [mysql]
      
      [mysqld]	# 配置mysqld片段内容,每一个[xxx]下面都是一个配置片段
      log-bin		# 表示开启bin-log功能
      binlog-do-db=test	# 指定在test库上开启bin-log功能
      # binlog-igore-db="mysql"	# 表示除了mysql库外其他库都开启bin-log功能
      server-id=1	# 设置一个id
      
    3. Master上,命令:sudo vim /etc/mysql/mariadb.conf.d/50-server.cnf 编辑Master服务器上的配置文件,将此配置文件中的bind-address配置项默认的127.0.0.1改为0.0.0.0 (或者本机某一物理网卡的ip地址),这样就开启Master服务器网络访问功能

    4. Master上,在MariaDB命令下创建用户账号给Slave服务器通过网络访问Master做bin-log日志的读取使用

    5. Master上,命令:sudo systemctl restart mariadb.service 重启服务使配置生效

    6. Slave上,命令:sudo vim /etc/mysql/mariadb.conf.d/50-server.cnf 编辑Master服务器上的配置文件,将此配置文件中的bind-address配置项默认的127.0.0.1改为0.0.0.0(或者本机某一物理网卡的ip地址)

    7. Slave上,命令:sudo vim /etc/mysql/conf.d/mysql.cnf 编辑Slave服务器上的配置文件,在其中添加配置内容,配置完成后的内容是

      [mysql]
      
      [mysqld]
      server-id=2	# 申明一下server-id
      
    8. Slave上,在MariaDB命令行下,指定Master服务器IP,以及使用的账号和密码

    9. Slave上,命令:sudo systemctl restart mariadb.service 重启服务使配置生效

    10. Slave上,在MariaDB命令行下,start slave 启动slave服务器(默认情况下是已经启动了的)

    11. Slave上,在MariaDB命令行下,show slave status\G; 查看slave服务器的状态

    12. Master上,一切准备就绪之后,打开Master服务器上锁,让其允许写入,在MariaDB命令行下,unlock tables;

    13. 在Master服务器上增加或减少数据等操作,查看Slave上有没有成功同步

11.4.5 调优工具 {#1145-调优工具}

  1. 命令:sudo apt install mysqltuner 安装调优工具
  2. 命令:mysqltuner 执行命令,根据显示的信息进行调优

11.5 Postgresql数据库 {#115-postgresql数据库}

11.5.1 概述 {#1151-概述}

  • 官方宣称:下一代关系型数据库
  • 高并发情况下性能优于MySQL
  • 侦听端口 TCP 5432

11.5.2 安装 {#1152-安装}

  • 命令:sudo apt install postgresql

11.5.3 安装后的必要操作 {#1153-安装后的必要操作}

  • 修改postgres账号身份认证方式为密码认证

    1. 命令:sudo -u postgres psql template1 postgresql安装过程中会创建一个操作系统账号postgressudo -u postgres 表示使用postgres账号执行后面的命令,就可以postgres账号登录到postgresql数据库中去,并使用template1数据库(也可以不指定数据库)(postgres账号相当于MySQL中的root账号)

    2. 在postgresql命令行中:alter user postgres with encrypted password '12345678' 将postgres账号的密码设置为12345678,修改完成之后,使用 \q 退出postgresql命令行

    3. 修改配置文件,命令:sudo vim /etc/postgresql/10/main/pg_hba.conf 编辑客户端登录相关的配置文件,目录中的10表示版本号,根据当前使用的版本填写相应的数字

      # 这个配置文件就是控制客户端登陆的时候,以谁的身份,以什么样的方式提交密码等关于登陆约束的配置文件
      
      # Database administrative login by Unix domain socket
      #local表示只能通过本机登陆,all表示登陆上去之后可以管理所有的数据库,postgres表示账号名称,peer表示身份认证方式
      local   all             postgres                                trust	# 这里默认是peer(表示登录时不需要密码),将其改为trust
      
      # TYPE  DATABASE        USER            ADDRESS                 METHOD
      
      # "local" is for Unix domain socket connections only
      local   all             all                                     peer
      # IPv4 local connections:
      host    all             all             127.0.0.1/32            md5
      # IPv6 local connections:
      host    all             all             ::1/128                 md5
      # Allow replication connections from localhost, by a user with the
      # replication privilege.
      local   replication     all                                     peer
      host    replication     all             127.0.0.1/32            md5
      host    replication     all             ::1/128                 md5
      
    4. 命令:sudo systemctl restart postgresql.service 重启postgresql数据库

    5. 修改成功使用使用,命令:psql -U postgres -W -d template1

      • -U表示登陆的账号名
      • -W表示登陆的过程中输入密码
      • -d表示登陆上去之后使用的数据库(可以不指定)

11.5.4 配置文件 {#1154-配置文件}

  • /etc/postgresql/version/main/ 配置文件目录,vsesion表示当前使用版本,例如使用的是10版本,则配置文件目录为 /etc/postgresql/10/main/

    • /etc/postgresql/10/main/pg_ident.confIDENT 身份认证配置

    • /etc/postgresql/10/main/postgresql.conf 网络身份认证配置,如果希望可以通过网络远程登录,将其中的listen_address = 'localhost'取消注释,并将localhost改为*****(侦听所有物理网卡上的5432端口)或者改为特定的物理网卡IP地址

    • /etc/postgresql/10/main/pg_hba.conf 登录约束配置文件,例如配置远程登录账号

      # 这个配置文件就是控制客户端登陆的时候,以谁的身份,以什么样的方式提交密码等关于登陆约束的配置文件
      
      # Database administrative login by Unix domain socket
      local   all             postgres                                trust	
      
      # TYPE  DATABASE        USER            ADDRESS                 METHOD
      
      # "local" is for Unix domain socket connections only
      local   all             all                                     peer
      # IPv4 local connections:
      host    all             all             127.0.0.1/32            md5
      # IPv6 local connections:
      host    all             all             ::1/128                 md5
      # Allow replication connections from localhost, by a user with the
      # replication privilege.
      local   replication     all                                     peer
      host    replication     all             127.0.0.1/32            md5
      host    replication     all             ::1/128                 md5
      
      # 新增配置允许网络登陆的账号
      # host表示允许网络上其他主机来登陆(如果写local则表示只能通过本机登陆)
      # all表示登陆后可以管理所有的数据库
      # postgres为可以进行远程登录的账户名
      # 192.168.2.190/24表示只允许这个IP来连接这个账户,注意后面要指定掩码
      # trust表示登陆的身份认证方式
      host	all				postgres		192.168.2.190/24			trust
      
      • 配置完成之后,重启服务,然后要进行远程登录的机器上执行,命令:sudo apt install postgresql-client 安装postgresql客户端程序
      • 安装完客户端程序之后,执行命令:psql -h 192.168.2.247 -U postgres -W来进行登陆
        • -h指定要登录机器的IP
        • -U指定登录账号
        • -W表示登陆过程中输入密码

11.5.5 创建账号 {#1155-创建账号}

  • 在postgresql命令行中,执行:create user zhangsan; 创建zhangsan账号
  • 第二种方式,命令:sudo -u postgres createuser lisi 创建lisi账号,需要输入数据库中postgres账号的密码

11.5.6 修改密码 {#1156-修改密码}

  • 在postgresql命令行中,执行:alter user lisi with encrypted password '12345678' 将lisi账号密码改为12345678

11.5.7 基本操作(增删改查等) {#1157-基本操作增删改查等}

  • Postgresql命令行中

    create database mydb;	-- 创建数据库mydb
    drop database mydb;		-- 删除数据库mydb
    
    \c mydb;	-- 用当前账号,使用数据库mydb
    \c - lisi;	-- 用lisi账号,使用当前数据库,中间的 - 表示当前数据库 
    
    \l;			-- 显示所有的数据库
    \dt;		-- 显示当前库中所有的表
    \d users;	-- 查看表的结构
    
    -- 创建表
    create table users (
    	uname varchar(20),
        password varchar(20),
        date date
    );
    
    insert into users values ('zhangsan','pass1','1999-1-1');	-- 插入数据
    
    copy users from '/home/lw/users.txt';	-- 批量向users表中插入数据,事先在users.txt中写好
    
  • 操作系统命令

    sudo -u postgres createdb mysql;	# 创建数据库mydb,需要输入数据库中postgres账号的密码
    sudo -u postgres dropdb mysql;		# 删除数据库mydb,需要输入数据库中postgres账号的密码
    

11.5.8 文档手册 {#1158-文档手册}

  • 命令:sudo apt install postgresql-doc-10 安装官方文档,后面的10表示版本,安装完毕后存放在**/usr/share/doc/postgresql-doc-10/html/index.html**下
  • https://www.postgresql.org/docs/ 网页版文档

11.6 NoSQL {#116-nosql}

11.6.1 概述 {#1161-概述}

  • NoSQL是一类数据库的统称
    • 每种NoSQL数据库为特定目的而设计,通常每种NoSQL数据库不能互操作
    • NoSQL不是也不可能成为SQL数据库的替代者
    • 适用于大数据集、高并发、大流量的应用场景(BI、BO适用于SQL)
    • NoSQL没有精确定义,且目前有很大争议
    • 并非完全不用SQL语句(Not only SQL、New SQL、ScalableSQL)
  • NoSQL的共性
    • 存储结构化数据,但不存储数据关系

11.6.2 优缺点 {#1162-优缺点}

  • 优点
    • 适合处理巨大数据集(比SQL数据库更多)
    • 按需扩展(横向增加主机节点)
    • 硬件透明,TOC低(传统小型机)
    • 数据模型松散(一说这事缺点),方便修改,不下线,快速dirty修复
  • 缺点
    • 大部分来自于小型开源项目,缺少技术支持,学习缺点陡峭,部署周期长
    • 项目本身年轻,功能和可靠性欠缺
    • 并不总符合ACID(原子性、一致性、隔离性、持久性)
    • 不保证即使正确记录,多主复制无法保证最新数据(适合互联网,不适合金融行业)
    • NoSQL没有绝对优势(视具体应用需要,大数据集)
    • 使用已知的技术栈,需要时再迁移(过早优化是万恶之源)
  • 优势和劣势是相对的

11.6.3 UnQL查询语言 {#1163-unql查询语言}

  • UnQL的新数据库查询语言
    • 非结构查询语言Unstructured Query Language
    • 也包含SELECT,INSERT,UPDATE,DELETE等语句
    • 不针对表操作,而是使用JSON描述的无序对象集合

11.6.4 键值对类型的NoSQL {#1164-键值对类型的nosql}

  • Key / Value Stroes
    • 键值对:数据即值(任何类型的比特数据),给数据起的名称即键
    • 没有元数据,无需事先定义数据类型(无需数据类型)
    • 适合存购物车、社交媒体内容(不适合身份证、信用卡信息)
  • Berkeley DB
    • 最早来自加州大学伯克利分校,先在归Oracle所有
    • 除键值存储,还支持SQL、JAVA交互方式(API)
    • 大型系统、嵌入式、移动设备均可用(Postfix、OpenLDAP)
  • Cassandra
    • 最早来自facebook,2008年被交给Apache开源
    • 也可作列存储数据库(与Hbase类似)
    • 群集内复制无中心节点,每个节点都可读写数据(Facebook、Twitter、Reddit都有使用)
  • Mencached / Memcache DB
    • 内存中数据库,加快访问速度(缓存解决方案)
  • Redis
    • 2009年发布,适用于性能和灵活性要求高于数据完整性的应用
    • C语言开发的内存中数据库
  • Riak
    • 来自于Amazon内部系统的一片技术paper
    • 用于云环境可扩展分布式数据库,无中心节点复制
    • 大型和小型环境部署工作量相同

11.6.5 文档类型的NoSQL {#1165-文档类型的nosql}

  • Document Store
    • 被设计来存储已有某种形式(如JSON或XML)结构化的数据
    • 通常作为应用和DB的一个中间层,保存特定类型的查询输出
  • CouchDB
    • 2005年由一个个人开发,2008年交给Apache开源
    • 设计目的是为WEB应用程序提供高可用数据库群集
    • CouchDB采用JSON文档存储对象(与大多NoSQL不同,支持ACID)
  • MongoDB
    • MongoDB采用JSON文档存储对象
    • 2009年由10gen发布,发展明显快于其他NoSQL数据库
    • 唯一一个开源数据库拥有商业技术支持(培训、顾问、咨询)
    • 支持分片,自动地跨服务器对数据进行分区,从RDBMS借鉴了很多特性
    • 默认端口:27017
  • BaseX
    • 用XML存储文档对象,2005年来自康斯坦丁大学
    • 轻量数据库,不支持多台多功能特性
    • 支持W3C推荐和标准、ACID-safe事务和各种API

11.6.6 大表类型存储NoSQL {#1166-大表类型存储nosql}

  • Wide Column Stroe
    • 通常被称为大表存储,使用带有Schema的大表存储数据
    • 与SQL数据库不同,不通过行而是列来定位数据
    • 不记录表之间的关系
  • Bigtable
    • 来自谷歌,为Mapreduce矿建设计
    • googleearth、Gmail、YouTube都有使用
  • Hbase
    • Hadoop使用的数据库
    • 适合大数据集的高并发实时请求(Amzaon、ebay、Facebook、IBM、linkedin都有使用)

11.6.7 图形存储NoSQL {#1167-图形存储nosql}

  • Neo4j
  • OrientDB

11.6.8 HyperGraphDB NoSQL {#1168-hypergraphdb-nosql}

  • FlockDB(Twitter存储社交图片)

11.6.9 MongoDB的使用 {#1169-mongodb的使用}

  • 安装

    • 命令:sudo apt install mongodb
  • 客户端登录

    • 本机登陆,命令:mongo
    • 远程登录,命令:mongo server_ip:port/db
    • mongoDB命令行中,help,显示帮助信息
  • 基本使用

    use mydb	# 如果没有这个库,那么就创建了这个库
    
    db.createCollection('users')	# 创建users集
    db.users.insert({'name':'zhangsan','uid':1001})	# 向users集中插入数据,name表示键,zhangsan是值
    db.users.insert({'name':'lisi','uid':101,'gid':[1001,1000,1111]})	# 插入数据,一个key可以对应多个value
    
    show dbs	# 显示所有的库
    show collections	# 显示所有的集
    
    db.users.find()	# 查询users集中所有的数据
    db.users.findOne({uid:1001})	# 查询users中uid为1001的一条数据
    db.users.findOne({uid:1001,name:'zhangsan'})	# 查询users中uid为1001且那么为zhangsan的一条数据
    db.users.findOne(gid:{$gt:1002})	# 查询users集中gid大于1002的一条数据
    db.users.find(gid:{$lt:1002})	# 查询users集中gid小于1002的所有数据
    db.users.findOne({uid:1001},{name:1})	# 查询users中uid为1001的一条数据,并且查询出来的值只显示name键和值
    db.users.findOne({uid:1001},{name:0})	# 查询users中uid为1001的一条数据,并且查询出来的值除了name键和值不显示,其他的键值都显示
    
    db.users.update({name:'zhangsan'},{$set:{uid:2222}})	# 将users集中name为zhangsan的uid设置为2222
    db.users.remove({name:'lisi'})	# 把users集中name为lisi的数据删除
    db.users.drop()	# 删除users集
    db.dropDatabase()	# 删除当前使用的数据库
    

第 12 章 LAMP & LEMP {#第-12-章-lamp--lemp}

12.1 LAMP {#121-lamp}

12.1.1 简介 {#1211-简介}

  • WEB应用程序基础套件
    • 操作系统(Linux)
    • WEB服务器(Apache、Nginx)
    • 数据库(MySQL、MariaDB、PostgreSQL)
    • 应用开发语言(PHP、Python、Perl)
  • 大量开源应用基于LAMP开发
    • WordPress
    • Wiki
    • Owncloud
    • phpmyadmin
    • ...

12.1.2 安装 {#1212-安装}

  • 安装LAMP(Linux+Apache+MySQL+PHP)
    • 自动安装
      1. 命令:sudo apt install tasksel
      2. 命令:sudo tasksel 然后选中要安装的LAMP预定义的软件集
    • 手动安装
      1. 命令:sudo apt install apache2 安装Apache2
      2. 命令:sudo apt install mysql-server 安装MySQL
      3. 命令:sudo apt install php libapache2-mod-php php-mysql 安装php

12.2 LAMP环境安装WordPress {#122-lamp环境安装wordpress}

12.2.1 简介 {#1221-简介}

  • WordPress
    • 开源免费的个人博客系统
    • 全球1/3的个人博客采用
    • 基于LAMP开发
    • 开箱即用的个人建站首选

12.2.2 安装 {#1222-安装}

  1. 命令:wget http://wordpress.org/latest.tar.gz 下载源码文件

  2. 命令:sudo tar -xvf latest.tar.gz -C /var/www/html/ 解压下载的压缩包到/var/www/html/目录下

  3. 更改目录权限 ,命令:sudo chown www-data:www-data -R /var/www/html/wordpress/ 更改wordpress目录和目录下的所有文件和目录的属组与属主为www-data账号,以www-data账号权限去运行

  4. 创建数据库

    -- 在MySQL命令行中,按步骤执行以下语句
    
    create database wpdb;	-- 创建给WordPress用的数据库,数据库名随意,最好不要一眼就看出来这个数据库是给WordPress用的
    
    -- 创建用户账号并只允许此账号使用让WordPress使用的数据库
    create user 'wpuser'@'localhost' identified by '12345678';	-- 创建用户账号
    grant all on wpdb.* to 'wpuser'@'localhost';	-- 赋予wpuser账号对wpdb数据库的所有权限
    
    flush privileges;	-- 刷新权限
    
    exit	-- 退出MySQL数据库
    
  5. 修改配置文件

    1. 命令:cd /var/www/html/wordpress/ 进入到WordPress源码目录

    2. 命令:sudo cp wp-config-sample.php wp-config.php 复制一份WordPress官方举例的配置文件,在复制出的wp-config.php上更改配置

      <?php
      
      /**
      
       * The base configuration for WordPress
      
       *
      
       * The wp-config.php creation script uses this file during the
      
       * installation. You don't have to use the web site, you can
      
       * copy this file to "wp-config.php" and fill in the values.
      
       *
      
       * This file contains the following configurations:
      
       *
      
       * * MySQL settings
      
       * * Secret keys
      
       * * Database table prefix
      
       * * ABSPATH
      
       *
      
       * @link https://codex.wordpress.org/Editing_wp-config.php
      
       *
      
       * @package WordPress
      
       */
      
      
      
      // ** MySQL settings - You can get this info from your web host ** //
      
      /** The name of the database for WordPress */
      
      define( 'DB_NAME', 'wpdb' );	// 配置让WordPress使用的数据库
      
      
      
      /** MySQL database username */
      
      define( 'DB_USER', 'wpuser' );	// 使用的MySQL账号
      
      
      
      /** MySQL database password */
      
      define( 'DB_PASSWORD', '12345678' );	// 使用的MySQL账号对应的密码
      
      
      
      /** MySQL hostname */
      
      define( 'DB_HOST', 'localhost' );	// 数据库所在的服务器IP
      
      
      
      /** Database Charset to use in creating database tables. */
      
      define( 'DB_CHARSET', 'utf8' );
      
      
      
      /** The Database Collate type. Don't change this if in doubt. */
      
      define( 'DB_COLLATE', '' );
      
      
      
      /**#@+
      
       * Authentication Unique Keys and Salts.
      
       *
      
       * Change these to different unique phrases!
      
       * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
      
       * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
      
       *
      
       * @since 2.6.0
      
       */
      
      define( 'AUTH_KEY',         'put your unique phrase here' );
      
      define( 'SECURE_AUTH_KEY',  'put your unique phrase here' );
      
      define( 'LOGGED_IN_KEY',    'put your unique phrase here' );
      
      define( 'NONCE_KEY',        'put your unique phrase here' );
      
      define( 'AUTH_SALT',        'put your unique phrase here' );
      
      define( 'SECURE_AUTH_SALT', 'put your unique phrase here' );
      
      define( 'LOGGED_IN_SALT',   'put your unique phrase here' );
      
      define( 'NONCE_SALT',       'put your unique phrase here' );
      
      
      
      /**#@-*/
      
      
      
      /**
      
       * WordPress Database Table prefix.
      
       *
      
       * You can have multiple installations in one database if you give each
      
       * a unique prefix. Only numbers, letters, and underscores please!
      
       */
      
      $table_prefix = 'wp_';
      
      
      
      /**
      
       * For developers: WordPress debugging mode.
      
       *
      
       * Change this to true to enable the display of notices during development.
      
       * It is strongly recommended that plugin and theme developers use WP_DEBUG
      
       * in their development environments.
      
       *
      
       * For information on other constants that can be used for debugging,
      
       * visit the Codex.
      
       *
      
       * @link https://codex.wordpress.org/Debugging_in_WordPress
      
       */
      
      define( 'WP_DEBUG', false );
      
      
      
      /* That's all, stop editing! Happy publishing. */
      
      
      
      /** Absolute path to the WordPress directory. */
      
      if ( ! defined( 'ABSPATH' ) ) {
      
      	define( 'ABSPATH', dirname( __FILE__ ) . '/' );
      
      }
      
      
      
      /** Sets up WordPress vars and included files. */
      
      require_once( ABSPATH . 'wp-settings.php' );
      
    3. 配置虚拟主机运行WordPress

      1. 命令:cd /etc/apache2/sites-available 进入到Apache虚拟主机配置目录下

      2. 命令:sudo cp 000-default.conf myblog.conf 复制一份默认的配置文件,在复制出的myblog.conf上修改配置

        <VirtualHost *:80>
        	# The ServerName directive sets the request scheme, hostname and port that
        	# the server uses to identify itself. This is used when creating
        	# redirection URLs. In the context of virtual hosts, the ServerName
        	# specifies what hostname must appear in the request's Host: header to
        	# match this virtual host. For the default virtual host (this file) this
        	# value is not decisive as it is used as a last resort host regardless.
        	# However, you must set it for any further virtual host explicitly.
        	ServerName www.myblog.com	# 修改服务器名称
        
        	ServerAdmin webmaster@localhost
        	DocumentRoot /var/www/html/wordpress	# 配置网站目录
        
        	# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        	# error, crit, alert, emerg.
        	# It is also possible to configure the loglevel for particular
        	# modules, e.g.
        	#LogLevel info ssl:warn
        
        	ErrorLog ${APACHE_LOG_DIR}/error.log
        	CustomLog ${APACHE_LOG_DIR}/access.log combined
        
        	# For most configuration files from conf-available/, which are
        	# enabled or disabled at a global level, it is possible to
        	# include a line for only one particular virtual host. For example the
        	# following line enables the CGI configuration for this host only
        	# after it has been globally disabled with "a2disconf".
        	#Include conf-available/serve-cgi-bin.conf
        </VirtualHost>
        
        # vim: syntax=apache ts=4 sw=4 sts=4 sr noet
        
      3. 启用新配置的站点 ,命令:sudo a2ensite myblog.conf

      4. 命令:sudo systemctl reload apache2.service 或 命令:sudo systemctl restart apache2.service 重新加载配置文件 或 重启服务,让配置生效

    4. 在浏览器访问WordPress站点,进行配置

12.2.3 更改语言为中文 {#1223-更改语言为中文}

  • 第一种方式
    1. 去WordPress官方网站上下载中文语言包
    2. 将下载的中文语言包解压到WordPress站点目录下的wp-content目录下
    3. 修改WordPress站点配置文件(例如这里是自己复制的wp-config.php),在配置文件中增加define('WPLANG','zh_CN');
  • 第二种方式
    • 下载WordPress中文版本,链接,安装步骤都是一样的

12.3 LAMP环境安装PHPMyAdmin {#123-lamp环境安装phpmyadmin}

12.3.1 简介 {#1231-简介}

  • 基于WEB应用的MySQL管理应用

12.3.2 安装 {#1232-安装}

  • 命令:sudo apt install phpmyadmin

12.3.3 配置 {#1233-配置}

  1. 命令:sudo vim /etc/apache2/apache2.conf 编辑Apache主配置文件,在其中添加

    include /etc/phpmyadmin/apache.conf		# 在Apache主配置文件中添加包含phpmyadmin的配置文件,这样才能访问phpmyadmin站点
    
  2. 命令:sudo systemctl restart apache2.service 重启Apache服务使配置生效

12.4 LAMP环境安装prestashop {#124-lamp环境安装prestashop}

12.4.1 简介 {#1241-简介}

  • 开源免费的电商平台系统
  • 全球有25万电商平台使用
  • 基于LAMP套件

12.4.2 安装 {#1242-安装}

  1. 安装依赖包 ,命令:sudo apt install php7.2-gd php7.2-xml php7.2-curl php7.2-zip

  2. 下载并解压源码文件

    1. 命令:wget https://download.prestashop.com/download/releases/prestashop_1.7.4.1.zip 使用wget下载最新的源码文件
    2. 解压下载的源码压缩文件到站点目录中去,命令:sudo unzip prestashop_1.7.4.1.zip -d /var/www/html/myshop
  3. 更改目录权限 ,命令:sudo chown www-data:www-data -R myshop/ 更改myshop目录和目录下的所有文件和目录属组与属主为www-data账号,以www-data账号权限去运行

  4. 创建数据库

    -- 在MySQL命令行中,按步骤执行以下语句
    
    create database myshop;	-- 创建给prestashop用的数据库,随便取什么名字
    
    -- 创建用户账号并只允许此账号使用让prestashop使用的数据库
    create user 'myshopuser'@'localhost' identified by '12345678';	-- 创建用户账号
    grant all on myshop.* to 'myshopuser'@'localhost';	-- 赋予myshopuser账号对myshop数据库的所有权限
    
    flush privileges;	-- 刷新权限
    
    exit	-- 退出MySQL数据库
    
  5. 配置虚拟主机运行prestashop

    1. 命令:cd /etc/apache2/sites-available 进入到Apache虚拟主机配置目录下

    2. 命令:sudo cp 000-default.conf myshop.conf 复制一份默认的配置文件,在复制出的myshop.conf上修改配置

      <VirtualHost *:80>
      	# The ServerName directive sets the request scheme, hostname and port that
      	# the server uses to identify itself. This is used when creating
      	# redirection URLs. In the context of virtual hosts, the ServerName
      	# specifies what hostname must appear in the request's Host: header to
      	# match this virtual host. For the default virtual host (this file) this
      	# value is not decisive as it is used as a last resort host regardless.
      	# However, you must set it for any further virtual host explicitly.
      	ServerName www.myshop.com	# 修改服务器名称
      
      	ServerAdmin webmaster@localhost
      	DocumentRoot /var/www/html/myshop	# 配置网站目录
      
      	# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
      	# error, crit, alert, emerg.
      	# It is also possible to configure the loglevel for particular
      	# modules, e.g.
      	#LogLevel info ssl:warn
      
      	ErrorLog ${APACHE_LOG_DIR}/error.log
      	CustomLog ${APACHE_LOG_DIR}/access.log combined
      
      	# For most configuration files from conf-available/, which are
      	# enabled or disabled at a global level, it is possible to
      	# include a line for only one particular virtual host. For example the
      	# following line enables the CGI configuration for this host only
      	# after it has been globally disabled with "a2disconf".
      	#Include conf-available/serve-cgi-bin.conf
      </VirtualHost>
      
      # vim: syntax=apache ts=4 sw=4 sts=4 sr noet
      
    3. 启用新配置的站点,命令:sudo a2ensite myshop.conf

    4. 启用prestashop需要的模块,命令:sudo a2enmod rewrite

    5. 命令:sudo systemctl reload apache2.service 或 命令:sudo systemctl restart apache2.service 重新加载配置文件 或 重启服务,让配置生效

  6. 在浏览器访问prestashop站点,进行配置

  7. 配置完成之后,删除install目录,命令:sudo rm -rf /var/www/html/myshop/install/

12.5 LEMP {#125-lemp}

12.5.1 简介 {#1251--简介}

  • LEMP
    • Linux + Nginx + MySQL + PHP
    • Nginx是来自于俄罗斯的发音,它的发音可以是Engine-x,所以称之为LEMP

12.5.2 安装 {#1252-安装}

  • 命令:sudo apt install nginx 安装Nginx
  • 命令:sudo apt install mariadb-server mariadb-client 安装mariaDB数据库和其客户端程序(或者MySQL数据库都可以)
  • 命令:**sudo apt install php7.2 php7.2-fpm php7.2-mysql ** 安装PHP和LEMP必须的模块

12.5.3 配置 {#1253-配置}

  • 配置php.ini ,命令:sudo vim /etc/php/7.2/fpm/php.ini

    cgi.fix_pathinfo=0	# 将这一项取消注释,并更改值为0
    date.timezone = Asia/shanghai	# 配置时区
    
  • 配置Nginx默认站点,让其支持PHP ,命令:sudo vim /etc/nginx/sites-available/default

    # pass PHP scripts to FastCGI server
            #
            location ~ \.php$ {
                    include snippets/fastcgi-php.conf;
            #
            #       # With php-fpm (or other unix sockets):
                    fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;	# 将这一项改为本机PHP进程名称,查看命令:ls /var/run/php
            #       # With php-cgi (or other tcp sockets):
            #       fastcgi_pass 127.0.0.1:9000;
            }
    
  • 命令:sudo systemctl restart nginx.service 重启Nginx服务,使配置生效

12.6 LEMP环境安装NextCloud {#126-lemp环境安装nextcloud}

12.6.1 简介 {#1261-简介}

  • 一款开源免费的网盘WEB应用

12.6.2 安装 {#1262-安装}

  1. 安装PHP依赖包,命令:sudo apt install php7.2-mbstring php7.2-xml php7.2-gd php7.2-curl php-imagick php7.2-zip php7.2-bz2 php7.2-intl

  2. 下载源码文件 ,命令:wget https://download.nextcloud.com/server/releases/nextcloud-13.0.4.zip (去官网上找最新的)

  3. 解压下载的源码文件到站点目录中 ,命令:sudo unzip nextcloud-13.0.4.zip -d /var/www/html/mycloud/

  4. 更改目录权限 ,命令:sudo chown www-data:www-data -R /var/www/html/mycloud/ 更改wordpress目录和目录下的所有文件和目录的属组与属主为www-data账号,以www-data账号权限去运行

  5. 创建数据库

    -- 在MySQL命令行中,按步骤执行以下语句
    
    create database cloud;	-- 创建给WordPress用的数据库,数据库名随意
    
    -- 创建用户账号并只允许此账号使用让WordPress使用的数据库
    create user 'user'@'localhost' identified by '12345678';	-- 创建用户账号
    grant all on cloud.* to 'user'@'localhost';	-- 赋予user账号对cloud数据库的所有权限
    
    flush privileges;	-- 刷新权限
    
    exit	-- 退出MySQL数据库
    
  6. [配置SSL](#10.4.6 让Nginx支持SSL_1)

    1. 生成证书

    2. 创建新站点配置文件,内容如下

      server {
          listen 80;	# 侦听80端口
          server_name www.mycloud.com;	# 
          return 301 https://www.mycloud.com$request_uri;	# 将http请求重定向到https上
      }
      
      server {
          listen 443 ssl http2;	# 侦听443端口,启用了http 2.0协议
          ssl_certificate /etc/ssl/certs/cloud.pem;	# 指定证书文件
          ssl_certificate_key /etc/ssl/private/cloud.key;	# 执行秘钥文件
      
          # Add headers to server security related headers
          add_header Strict-Transport-Security "max-age=31536000" always;	# 增加了SSL增强版协议的支持
          add_header X-Content-Type-Options nosniff;
          add_header X-XSS-Protection "1; mode=block";	# XSS保护的头部
          add_header X-Robots-Tag none;
          add_header X-Download-Options noopen;
          add_header X-Permitted-Cross-Domain-Policies none;
      
          root /var/www/html/nextcloud/;	# 站点路径
      
          location = /robots.txt {
              allow all;
              log_not_found off;
              access_log off;
          }
      
          location = /.well-known/carddav {
              return 301 $scheme://$host/remote.php/dav;
          }
          location = /.well-known/caldav {
             return 301 $scheme://$host/remote.php/dav;
          }
      
          location ~ /.well-known/acme-challenge {
            allow all;
          }
      
          client_max_body_size 512M;
          fastcgi_buffers 64 4K;
      
          gzip off;
      
          error_page 403 /core/templates/403.php;
          error_page 404 /core/templates/404.php;
      
          location / {
             rewrite ^ /index.php$uri;
          }
      
          location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
             deny all;
          }
          location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
             deny all;
           }
      
          location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
             include fastcgi_params;
             fastcgi_split_path_info ^(.+\.php)(/.*)$;
             fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
             fastcgi_param PATH_INFO $fastcgi_path_info;
             fastcgi_param modHeadersAvailable true;
             fastcgi_param front_controller_active true;
             fastcgi_pass unix:/run/php/php7.2-fpm.sock;
             fastcgi_intercept_errors on;
             fastcgi_request_buffering off;
          }
      
          location ~ ^/(?:updater|ocs-provider)(?:$|/) {
             try_files $uri/ =404;
             index index.php;
          }
      
          location ~* \.(?:css|js)$ {
              try_files $uri /index.php$uri$is_args$args;
              add_header Cache-Control "public, max-age=7200";
              add_header X-Content-Type-Options nosniff;
              add_header X-XSS-Protection "1; mode=block";
              add_header X-Robots-Tag none;
              add_header X-Download-Options noopen;
              add_header X-Permitted-Cross-Domain-Policies none;
              access_log off;
         }
      
         location ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ {
              try_files $uri /index.php$uri$is_args$args;
              access_log off;
         }
      }
      
    3. 启用新配置的站点 ,命令:sudo ln -s /etc/nginx/sites-available/mycloud /etc/nginx/sites-enabled/mycloud

    4. 重启服务,命令:sudo systemctl restart nginx.service 重启Nginx服务

  7. 创建数据保存的目录

    • 建议不要位于/var/www/html/nextcloud网站目录下
    1. 命令:sudo mkdir /var/www/html/data 创建保存数据的目录
    2. 命令:sudo chown www-data:www-data -R /var/www/html/data/ 更改data目录属组属主
  8. 在浏览器访问NextCloud站点,进行配置

12.6.3 客户端程序 {#1263-客户端程序}

  • Linux
    1. 命令:sudo add-apt-repository ppa:nextcloud-devs/client 添加源
    2. 命令:sudo apt update 更新
    3. 命令:sudo apt install nextcloud-client 安装nextcloud客户端

12.7 基于WEB远程管理------Cockpit {#127-基于web远程管理cockpit}

12.7.1 简介 {#1271-简介}

  • Cockpit
    • 基于WEB的远程管理应用
    • 将所有组件打包在一起
    • 不依赖单独部署的LAMP/LEMP

12.7.2 安装 {#1272-安装}

  • 命令:sudo apt install cockpit cockpit-docker

12.7.3 访问 {#1273-访问}

  • 默认使用的是9090端口
  • 使用系统的账号和密码登录

12.8 基于WEB实时监控------Netdata {#128-基于web实时监控netdata}

12.8.1 简介 {#1281-简介}

  • NetData
    • 基于WEB构建的Linux系统实时性能监视工具
    • CPU、内存、硬盘、网络、进程、硬件
    • 占用系统资源少(1-3%)
    • 实时告警

12.8.2 安装 {#1282-安装}

  1. 安装依赖包 ,命令:sudo apt-get install git zlib1g-dev uuid-dev libmnl-dev gcc make autoconf autoconf-archive autogen automake pkg-config curl python python-yaml python-mysqldb python-psycopg2 nodejs lm-sensors netcat

  2. 下载并执行脚本文件 ,命令:bash <(curl -Ss https://my-netdata.io/kickstart-static64.sh)

12.8.3 访问 {#1283-访问}

  • 默认端口:19999

第 13 章 聊天服务 {#第-13-章-聊天服务}

13.1 聊天服务 {#131-聊天服务}

13.1.1 概述 {#1311-概述}

  • 发明网络的目的是沟通(信息交换)
  • 高效的沟通是生产力
    • 骑马送信,电报,电话,邮件
    • IRC、BBS、IM
  • 为什么不用QQ、微信、Telegram
    • 企业信息流经他人服务器(泄密)
    • 内部信息内部传递效率更高
    • 更专注于公司内部工作内容

13.2 IRC服务搭建 {#132-irc服务搭建}

13.2.1 简介 {#1321-简介}

  • Internet Relay Chat(因特网中继聊天)
  • 出现于1988年(为取代MUT而诞生)
  • 是一种通过网络的群体即时聊天方式(也可以用于个人间聊天)
  • 公开的协议(TCP和SSL协议)
  • IRC服务器可以连接其他的IRC服务器形成一个IRC网络
  • 大多数的IRC服务器不需要客户注册登录(nickname)
  • 目前已经很少见(黑客和老派的技术群体的挚爱)
  • 部分流服务商依赖IRC协议进行信息传递

13.2.2 安装服务端 {#1322-安装服务端}

  • 安装配置简单,系统资源占用低
  • 命令:sudo apt install ircd-hybrid
  • 默认端口是6667

13.2.3 服务端配置 {#1323-服务端配置}

  • 设置管理员密码( operator )

    • 在配置文件中配置管理员账号密码时,ircd-hybrid不允许在配置文件中直接写明文密码,所以要求使用mkpasswd命令先将明文密码转成密文,然后将密文写入到配置文件中
    1. 命令:mkpasswd 12345678 将后面的12345678转成密文,也可以直接输mkpasswd命令,然后按提示输入要加密的密码(这样输入的密码看不见)

    2. 编辑配置文件 ,命令:sudo vim /etc/ircd-hybrid/ircd.conf

      # 服务器配置
      serverinfo {
      	name = "irc.lab.com"	# 设置IRC服务器的名字,随意,这里取解析到irc服务器上的名字
      	description = "LABIRC"	# 对这台IRC服务的描述
      
      	network_name = "BJ"		# 在哪个网络,比如说公司大,全国各地都有,此台在BJ
      	network_name = "This is BJ Network"		# 在哪个网络进行描述
      
      	hub = no;	# 如果有多个IRC服务器,是否设置此台为中心
      
      	default_max_clients = 512;	# 客户端最大连接数
      
      	max_nick_length = 15;	# 昵称最大长度
      
      	max_topic_length = 300;	# 话题的最大长度
      };
      
      # 配置管理员
      operator {
      	name = "admin";	# 管理员的账号名
      	user = "*@*";	# 所有账号在任何主机上都能连接(只要有用户名和密码就能获得管理员权限),前面的*表示账号,后面的*表示IP地址(需要加掩码)
      	password = "OrtiN2aMcYFq2";	# 将mkpasswd生成的密文放在这里,登录时用原密码明文登录就可以
      };
      
    3. 重启服务使配置生效 ,命令:sudo systemctl restart ircd-hybrid.service

  • 客户端登陆显示信息

    • 编辑配置文件,命令:sudo vi /etc/ircd-hybrid/ircd.motd 是一个文本文件,里面写的内容,在客户端登录时会显示在客户端上

13.2.4 客户端 {#1324-客户端}

  • 登录过程

    • 当客户端连接IRC服务器时,IRC服务器会反连客户端ident服务端口,如果客户端机器没有安装ident服务,那么客户端就没法将客户端机器的机器名,要登录的账号密码等发送给IRC服务器,那么IRC服务器就会拒绝登录,所以必须要安装IRC客户端及ident服务
  • 安装

    • Linux
      1. 命令:sudo apt install irssi 安装IRC客户端程序
      2. 命令:sudo apt install ident2 安装ident服务
    • Windows
      • mIRC ,下载链接
  • 登录

    • Linux

      • 命令:irssi -c 192.168.2.247

    • Windows

      1. 打开mIRC,选择一个服务器

      2. 添加一台IRC服务器

      3. 给ident服务随便设置一个User ID

      4. 选择刚刚添加的IRC服务器

      5. 取一个昵称和别名

13.2.5 常用命令 {#1325-常用命令}

  • 将自己切换为管理员账号,IRC命令:/open 账号名 明文密码,例如:/oper admin 123456

  • 显示所有的频道,IRC命令:/channel list

  • 创建频道,IRC命令:/channle add -auto #频道名 freenode,例如:/channle add -auto #Football freenode

  • 进入频道,IRC命令:/join 频道名,例如:/join #football

  • 显示帮助信息,IRC命令:/help

  • 查看某个channel(或其他)的使用方法,/help channel

    常用命令 命令说明 使用举例 /links 列服务器连接信息 /links /list 列出所有聊天室 /list /nick 名字 更换名字 /nick 林桃子67 /ns register 密码 注册名字 /ns regiser 123456 /pass 密码 验证名字密码 /pass 123456 /ns set password 新密码 修改名字密码 /ns set password 654321 /mode 自己名字 +/-i 设置昵称是否隐藏 /mode 林桃子67 +/-i /mode 自己名字 +/-s 是否收服务器信息 /mode 是我 +/-s /run 文件名 运行程序或文件 /run jpbot.exe /whois 名字 查看网友的信息 /whois 是我 /userhost 名字 查看网友的IP地址 /userhost 是我 /ns info 名字 查名字注册信息 /ns info 名字 /ns status 名字 查询用户状态 /ns status 名字 /who 看看谁在线上 /who /who #房间名 看看谁在房间中 /who #林桃子67的房间 /names #房间名 列房间中所有用户 /names #日本女性的房间 /me 要说的话 使用动作表情 /me 大家好,今天你IRC了么 /say 要说的话 在当前频道说话 /say 老公,想我了吗 /notice 名字 要说的话 向某人发出通告 /notice 远方的风 有事找你 /query 名字 发送信息 开小窗和他私聊 /query 夕阳天使 hi,久违了你 /privmsg 名字 发送信息 开小窗发送信息 /privmsg 天使源 hi,久违了你 /msg 他的名字 信息内容 给他悄悄发送信息 /msg 于天 你好! /msg 房间名字 信息内容 向房间全体成员说 /msg #日语角 大家好! /omsg #房间名字 要发的信息 仅对屋中的@说话 /omsg #日语角 见吴山了没有 /amsg 要发的信息 多个频道同发信息 /amsg 我老公在那里呢 /onotice 房间名字 要发的话 在该屋对所有op说 /onotice #日语角 水素死翘了 /close -m 关闭所有小窗聊天 /close -m /ignore 他的名字 忽略你讨厌的人 /ignore 杨过,shll, /ignore -T * 忽略别人CTCP查询 /ignore -T * /join #房间名 加入一个房间 /join #林桃子67的房间 /away 给出离开的原因 离开并给出原因 /away 对不起GG,我男友来了 /away 取消离开设置 /away /part #房间名 退出信息 退出当前房间 /part #日语角 bye大家 /partall 退出信息 退出所有房间 /partall byeall /quit 退出信息 退出IRC退出连接 /quit 今天实在是累了,bye /exit 退出信息 关闭irc并退出 /exit 睡觉觉去了 /disconnect 退出信息 与服务器断开连接 /disconnect 我是故意断线的 /server bj.irc.263.net 6667 更换irc服务器 /server bj.irc.263.net 6667 /cs register #房间名字 密码 你对房间的描述 注册自己的房间 /cs register #

    林桃子67的房间 123456 我是桃子67我怕谁 /topic #房间名字 主题内容 更改房间主题 /topic #日语角 欢迎你朋友 /invite 他的名字 #房间名 邀请别人来房间 /invite 紫丁香花 #日语角 /kick #房间名 他的名字 把人踢出房间 /kick #林桃子67的房间 PC100 /mode #房间名 +/-b 他的名字 把某人禁止/解禁 /mode #林桃子67的房间 +/-b 然采 /mode #房间名 +/-o 朋友名字 给朋友加/减帽子 /mode #林桃子67的房间 +/-o 然采 /auto -r on|off|他的名字 #频道名字 自动朋友加/减帽 /auto -r [on然采 ]#林桃子67的房间 出错了 /mode #房间名 +/-l 人数 设置限制房间人数 /mode #日语角 +/-l 100 /mode #房间名字 +/-n 禁不禁止外部信息 /mode #日语角 +/-n /mode #房间名字+/-m 限制发言仅@/+说 /mode #房间名字 +/-m /mode #房间名字 +/-i 设置邀请模式 /mode #日语角 +/-i /mode #房间名字 +/-p 是否设置私有模式 /mode #日语角 +/-p /mode #房间名字 +/-s 是否设置秘密模式 /mode #日语角 +/-s /mode #房间名字 +/-t 是否只@能改主题 /mode #日语角 +/-t /mode #房间名 +k 密码 给房间加密码 /mode #日语角 +k 123456 /join #房间名 密码 进入有密码的房间 /join #日语角 123456 /channel 调出频道模式设置 /channel /cs info #房间名字 查看频道注册信息 /cs info #日语角

    nickserv 昵称服务 更换昵称 /nick 你要换的新名字 注册昵称 /ns register 密码 邮箱 认证昵称 /ns identify 名字密码 这个也认证昵称 /pass 名字密码 昵称保护 /ns set kill on/off 昵称安全 /ns set secure on/off 昵称保密 /ns set private on/off 修改密码 /ns set password 新密码 昵称邮箱 /ns set email 你的邮箱 昵称主页 /ns set url http://52irc.org 隐藏邮件 /ns set hide emall On/off 隐藏网络地址 /ns set hide usermask On/off 隐藏退出信息 /ns set hide quit On/off 杀掉盗用你名字者 /ns ghost 你的妮称 密码 注销昵称 /ns drop 你的妮称(得先认证)

    chanserv 频道服务 查看房间信息 /cs info #频道名字 注册房间 /cs register #频道名字 密码 简介 认证你的房主身份 /cs identify #频道名字 频道密码 设置房间的主页 /cs set #频道名字 url 主页地址 设置房间的邮箱 /cs set #频道名字 email 邮件地址 设置房间的主题 /cs set #频道名字 topic 主题内容 保留房间的主题 /cs set #频道名字 keeptopic on/off 锁定房间的主题 /cs set #频道名字 topiclock on/off 设置新的房间主人 /cs set #频道名字 founder 新任房主 设置房间的新密码 /cs set #频道名字 password 频道密码 设置房间安全控制 /cs set #频道名字 secure on/off 设置房间管理员控制 /cs set #频道名字 secureops on/off

    memoserv 留言服务 列表所有留言 /ms list 列表最新留言 /ms list new 阅读最新留言 /ms read last 阅读特定留言 /ms read 留言号码 删除指定的留言 /ms del 留言号码 删除所有的留言 /ms del all 给人发送留言 /ms send 对方妮称 留言内容

    chanserv 频道服务 设置频道进入信息 /cs set #频道名字 entrymsg 所设置信息 用服务器给客人加帽子 /cs op #频道名字 对方名字 服务器摘掉某人的帽子 /cs deop #频道名字 对方名字 让服务器为自已解ban /cs unban #频道名字 增加一人到房踢列表/cs akick #频道名字 add 对方名字 删除一人到房踢列表/cs akick #频道名字 del 对方名字 查看房踢列表/cs akick #频道名字 list 清除房间的所有ban /cs clear #频道名字 bans 清除房间的模式设置 /cs clear #频道名字 modes 清除房间的所有帽子 /cs clear #频道名字 ops 清除房间的所有用户 /cs clear #频道名字users 注销房间 /cs drop #频道名字--------------------------------------------------------------------- CTCP查询命令 查对方反映速度 /ctcp 对方名字 ping 查对方当地时间 /ctcp 对方名字 time 查对方软件版本 /ctcp 对方名字 version 查对方的用户信息 /ctcp 对方名字userinfo 查对方的用户信息 /ctcp 对方名字 clientinfo

13.3 Mattermost {#133-mattermost}

13.3.1 简介 {#1331-简介}

  • 团队群聊 SaaS 平台
  • 使用 Go 语言开发
  • 独立于操作系统的二进制部署方式
  • 基于 MySQL 、 Postgresql 数据库
  • Slack 的替代选择方案(兼容 Slack )
  • 全平台客户端支持( WEB )
  • 免费版、收费版
  • 适用于企业内部团队文件共享和信息交换
  • 默认端口:8065

13.3.2 安装和配置 {#1332-安装和配置}

  1. 安装和配置数据库

    1. 安装数据库

      • 命令:sudo apt install mysql_server
        • 安装完成之后,运行命令:sudo mysql_secur_installation
    2. 配置数据库

      create database mattermost;		-- 创建给Mattermost使用的数据库
      
      create user 'muser'@'%' identified by '12345678';	-- 创建muser账号并设置密码,允许此账号允许任何IP地址来连接
      grant all privileges on mattermost.* to 'muser'@'%';-- 赋予muser账号对mattermost数据库下所有表的所有权限
      
      flush privileges;	-- 刷新权限
      
  2. 去Mattermost官方网站下载最新版本进行安装

    1. 下载最新版本的安装包 ,命令:wget https://releases.mattermost.com/5.1.0/mattermost-team-5.1.0-linux-amd64.tar.gz
    2. 解压下载的安装包 ,命令:tar -xvzf mattermost-team-5.1.0-linux-amd64.tar.gz
    3. 将解压出来的目录移到/opt目录下(习惯上个人安装的应用都放在这个目录,也方便管理) ,命令:sudo mv mattermost /opt
    4. 创建data目录来保存聊天过程中发送的文件 ,命令:sudo mkdir /opt/mattermost/data/
    5. 从安全的角度来说,给每个应用创建专门运行的账号,不要用管理员账号运行 ,命令:sudo useradd -rU mattermost 创建mattermost账号和mattermost账号组
    6. 将mattermost目录属组与属主都改为专门给它运行的账号 ,命令:sudo chown -R mattermost:mattermost mattermost
    7. 赋予mattermost账号组,对/opt/mattermost目录有写的权限 ,命令:sudo chmod g+w /opt/mattermost
  3. 配置Mattermost

    1. 修改Mattermost主配置文件,配置为它创建的数据库和连接数据库的账号及密码,并将默认语言设置为中文 ,命令:sudo vim /opt/mattermost/config/config.json

      // 修改数据库配置段
      "SqlSettings": {
              "DriverName": "mysql",	// 连接的数据库类型
              "DataSource": "muser:12345678@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s&writeTimeout=30s",	// 设置连接数据库的账号及密码(muser:12345678),IP和端口(@tcp(localhost:3306)),要连接的数据库(/mattermost),其他的自己看情况修改
              "DataSourceReplicas": [],
              "DataSourceSearchReplicas": [],
              "MaxIdleConns": 20,
              "ConnMaxLifetimeMilliseconds": 3600000,
              "MaxOpenConns": 300,
              "Trace": false,
              "AtRestEncryptKey": "",
              "QueryTimeout": 30
          },
      
      // 修改语言为中文
      "LocalizationSettings": {
              "DefaultServerLocale": "zh-CN",
              "DefaultClientLocale": "zh-CN",
              "AvailableLocales": "zh-CN"
          },
      
      
    2. 测试数据库连接 ,命令:sudo -u mattermost /opt/mattermost/bin/mattermost 以mattermost账号运行**/opt/mattermost/bin/mattermost**程序,如果看见启动信息中显示了以在8065端口上工作了即表示配置没有问题

  4. 创建并配置Mattermost Systemd服务单元文件

    1. 创建和编辑服务单元文件 ,命令:sudo vim /lib/systemd/system/mattermost.service

      # 如果让Mattermost使用的是Postgresql数据库,则要将此文件中的三处mysql.service改为postgresql.service
      [Unit]
      Description=Mattermost		# 服务的描述
      After=network.target		# 启动此服务之前先启动network.target服务
      After=mysql.service			# 启动此服务之前先启动mysql.service服务
      Requires=mysql.service
      [Service]
      Type=notify
      ExecStart=/opt/mattermost/bin/mattermost	# 启动哪一个具体的应用程序
      TimeoutStartSec=3600		
      Restart=always
      RestartSec=10
      WorkingDirectory=/opt/mattermost
      User=mattermost				# 使用哪个账号启动此服务
      Group=mattermost			
      LimitNOFILE=49152
      [Install]
      WantedBy=mysql.service
      
    2. 重新加载systemd后台文件 ,命令:sudo systemctl daemon-reload

    3. 启动Mattermost服务 ,命令:sudo systemctl start mattermost.service

    4. 设置Mattermost服务随操作系统启动 ,命令:sudo systemctl enable mattermost.service 会将 /lib/systemd/system/mattermost.service创建一个符号链接,链接到/etc/systemd/system/mysql.service.wants/mattermost.service,这样Mattermost就能随操作系统启动而启动了

  5. 打开浏览器访问Mattermost,例如http://192.168.2.247:8065

    1. 创建管理员账号,默认创建的第一个账号就被赋予了system_admin 角色(管理员)

    2. 创建团队

    3. 基本配置

    4. 启用电子邮件通知

    5. 配置文件存储

13.3.3 客户端程序 {#1333-客户端程序}

  • 官网有各个平台的客户端程序

13.4 Openfire {#134-openfire}

13.4.1 简介 {#1341-简介}

  • 开源免费的 IM 即时通信服务器
  • Real-time collaboration ( RTC )
  • 由 JAVA 开发(需要 JAVA 运行环境)
  • 使用拓展通讯和表示协议 (XMPP)
    • Extensible Messaging and Presence Protocol
  • 号称单台服务器可支持上万并发用户
  • 兼容所有支持 XMPP 协议的客户端( spark )
  • 支持插件开发
  • 支持 mysql 、 postgresql 、内建数据库
  • 支持 LDAP 、 TLS 、群集部署
  • 默认端口:9090

13.4.2 安装 {#1342-安装}

  1. 配置JAVA运行环境

    1. 安装jdk(选择openjdk或者Oracle的jdk都可以) ,命令:sudo apt install openjdk-8-jdk
    2. 检测JAVA是否安装成功 ,命令:java -version
  2. 安装和配置数据库

    1. 安装数据库

      • 命令:sudo apt install mysql-server
        • 安装完成之后,运行命令:sudo mysql_secur_installation
    2. 配置数据库

      create database openfire;		-- 创建给Openfire使用的数据库
      
      grant all privileges on openfire.* to 'openfire'@'%' identified by '12345678';	-- 创建openfire账号,允许通过任何IP连接,并赋予对openfire数据库下所有表的所有权限,账号密码为12345678
      
      flush privileges;	-- 刷新权限
      
  3. 去Openfire官方网站下载最新版本deb格式安装包进行安装

    1. 安装deb文件 ,命令:sudo dpkg -i openfire_4.4.0_all.deb

    2. 导入数据库表,进入mysql命令行中

      use openfire;
      source /usr/share/openfire/resources/database/openfire_mysql.sql;	-- 导入数据
      show tables;
      
  4. 打开浏览器访问Openfire,例如http://192.168.2.247:9090

    1. 选择语言

    2. 服务器设置

    3. 数据库设置

      • 选则标准数据库连接

      • 选择要连接的数据库类型
        • 例如这里选mysql数据库,因为要进行中文的传输,所以将编码设置为Unicode和UTF-8,将数据库URL写为:jdbc:mysql://127.0.0.1/openfire?useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&rewriteBatchedStatements=true

    4. 外形设置

    5. 管理员账户

13.4.3 客户端程序 {#1343-客户端程序}

  • 官网有各个平台的客户端程序

  • 登录时报错,Unable to verify certificate,这是因为openfire使用的是自签名证书,系统默认是不信任的,需要在高级中设置

13.5 Rocket.Chat {#135-rocketchat}

13.5.1 简介 {#1351-简介}

  • 与 Mattermost 类似
  • 团队群聊 SaaS 平台
  • Slack 的替代选择方案
  • 全平台客户端支持( WEB )
  • 适用于企业内部团队文件共享和信息交换
  • 独立于操作系统的Snap部署方式
  • 官方建议使用端口:3000

13.5.2 安装 {#1352-安装}

  • 官方文档

  • 自动安装

  • 手动安装(暂不可行)

    1. 安装mongoDB数据库 ,命令:sudo apt install mongodb
      • 生产环境下,配置好mongoDB数据库群集
    2. 安装依赖软件包 ,命令:sudo apt-get install nodejs build-essential npm
      • 指定Node.js版本,目前Rocket.Chat官方要求需要Node.js的8.11.4版本,点击查看现在所需要的版本
        1. 安装npm ,命令:sudo apt install -g n
        2. 指定版本 ,命令:sudo n 8.11.4
    3. 官网下载最新版本
      1. 解包下载的包 ,命令:tar zxvf rocket.chat-1.3.1.tar
      2. 解包完成之后会得到bundle目录,进入./bundle/programs/server,在server目录下 ,执行安装命令:npm install
      3. 定义系统变量
        • 指定Rocket.Chat的URL地址 ,命令:export ROOT_URL=http://192.168.2.247:3000 如果有域名就写域名
        • 指定Rocket.Chat服务端访问的数据库URL ,命令:export MONGO_URL=mongodb://localhost:27017/rocketchat 连接本机的mongodb
        • 指定使用的端口号 ,命令:export PORT=3000 官方建议使用3000端口
    4. 启动Rocket.Chat服务端程序 ,命令:node main.js

第 14 章 邮件服务 {#第-14-章-邮件服务}

14.1 电子邮件基础 {#141-电子邮件基础}

14.1.1 概述 {#1411-概述}

  • 电子邮件
    • 快速、便捷、通用、异步通信方式
    • 1965年最早由 MIT 发明并开源(最早用于同主机用户间通信)
    • 1971年确定邮件地址以 @ 符号连接(在不同主机之间传递信息)
    • MIME 类型扩展邮件从纯文本到传递文件(文档、图片、媒体)
    • 邮件可被伪造、邮件炸弹、垃圾邮件
  • 传统物理邮件
    • 写信 --> 到本地邮局 --> 目的邮局 --> 收件人
  • 电子邮件
    • Client1 --> Server1 --> Server2 --> Client2(邮件地址通过DNS 解析完成邮件路由)
    • 无收件人返回报错(不通知),连不上目标服务器周期重发(直至失败)

14.1.2 邮件协议 {#1412-邮件协议}

  • SMTP
    • Simple Mail Transfer Protocol(简单邮件协议)
    • 默认端口:25
    • MTA (Mail transfer agents ) 之间通信协议(SMTPD)
      • 发件和收件都是通过MTA组件来实现的
      • 由很多个小程序组合实现MTA所有功能
    • 客户端发邮件 MUA --> MTA 也是用 SMTP 协议

14.1.3 邮箱存储格式 {#1413-邮箱存储格式}

  • MBOX
    • 传统的 mbox 格式邮箱存储将所有邮件存于一个文件中(索引定位具体邮件)
    • 文件和索引损坏可能造成邮件丢失,故障恢复困难
    • 不适易存储于 NSF 挂在目录中,加入网络发送故障就有可能会造成邮箱存储发送损坏
  • MAILDIR
    • Maildir 格式包含三个子目录/cur、/new、/tmp,每个邮件分隔独立保存
    • 可并行访问,性能更高(mbox 不支持)
    • 可用 NFS 作为邮箱存储

14.1.4 工作原理 {#1414-工作原理}

14.1.5 邮件 {#1415-邮件}

  • 邮件结构
    • 信封:用于邮件路由,对用户透明不可见
    • 邮件
      • 邮件头:邮件路由传输过程的记录日志
      • 邮件体:邮件要传递的具体内容
  • SPAM
    • 垃圾邮件,不请自来的邮件(Junk)
    • 处理浪费时间、网络带宽、存储空间
  • 病毒、木马、蠕虫、钓鱼邮件
    • 包含恶意义附件、链接、伪装、诈骗内容
    • 存在安全风险,谨慎打开陌生邮件
  • 写邮件规范
    • 收件人为事件直接相关人
    • 次要相关人按职位顺序 CC、BCC
    • 主题简洁清晰,高度概括
    • 保证表述清楚的前提下邮件内容尽可能短(避免语法错误)
    • 适当使用表情符
    • 回复、转发完整邮件流(禁止新写邮件作为回复)
    • 压缩附件
    • 附个人签名

14.2 电子邮件架构 {#142-电子邮件架构}

14.2.1 概述 {#1421-概述}

14.2.2 MTA {#1422-mta}

  • MTA是用在邮件主机上的软件,它是主要的邮件服务器
  • MTA就是"邮件传送代理"的意思,用户寄信与收信时,都找MTA,它负责帮用户传送

14.2.3 常见的MTA软件包 {#1423-常见的mta软件包}

  • Sendamil
    • 处理着绝大多数互联网电子邮件
    • 开源免费版 / 商业版(GUI 界面)
    • 配置过于复杂(默认配置已经可以良好工作)
    • 功能全面但性能不占优势
  • Postfix
    • 来自于 IBM 的开源 MTA (Ubuntu 默认首选 MTA)
    • 速度优于 Sendmail,配置管理更简单(配置文件,命令都可以配置)
    • 可以平滑替换 Sendmail(模块化)
  • Qmail
    • Postfix 的可替代选择(模块化的 MTA,每个模块使用不同的用户账号运行、每一个模块的配置文件都是单独的)
    • 设计初衷是实现取代 Sendmail 的更安全快速的 MTA
    • 从 Sendmail 迁移到Qmail 过程复杂
    • 众多插件,包含Web Mail、POP 服务
  • Exim
    • 比 Sendmail / Postfix 更安全快速,但配置方式不同
    • 与 Qmail 都使用 maildir 格式邮箱存储

14.2.4 MDA {#1424-mda}

  • MDA ( Mail Delivery Agent )
    • MTA 可直接投递和读取邮件
      • 更多时候邮件投递由 MDA 完成
    • MDA 比 MTA 额外实现自动过滤、回复、 规则转存、 杀毒等
    • 主要的功能就是将MTA接收的信件依照信件的流向(送到哪里),将该信件放置到本机账户下的邮件文件中(收件箱),或者再经由MTA将信件送到下个MTA。如果信件的流向是到本机,这个邮件代理的功能就不只是将由MTA传来的邮件放置到每个用户的收件箱,它还可以具有邮件过滤(filtering)与其他相关功能

14.2.5 常见的MDA软件包 {#1425-常见的mda软件包}

  • Mailx
    • MDA + MUA(ubuntu 的默认 MDA)
    • 来自 MTA 的邮件交给 Mailx 投递到用户邮箱(/var/mail/)
    • 主目录下 创建.forward 文件写入要转发给的邮箱,实现自动转发
  • mail.local
    • 常用于 BSD 的 MDA 程序
    • 功能使用与 Mailx 类似
  • procmail
    • 最流行的 MDA 之一
    • Recipes 允许用户自定义邮件处理脚本(.procmailrc)

14.2.6 MUA {#1426-mua}

  • MUA( Mail User Agent )

    • 读取和展示邮箱中的邮件(不进行邮件传递)
    • 3种MUA类型区分原则:在哪读邮件 / 邮件显示格式(MIME)

14.2.5 常见的MUA软件包 {#1425-常见的mua软件包}

  • Mailx
    • 服务器本地直接读取邮箱, mail命令
    • 字符界面,不支持MIME类型,纯文本方式显示
    • 只能在邮件服务器本地读取邮箱
  • Dovecot
    • 远程客户端访问邮箱
    • POP3(Post Office Protocol version 3)邮局协议版本3
      • 默认端口:110
      • POP3协议适合单一客户端
        • 比如只有笔记本有客户端收邮件,不会有在手机、平板、PC上同时收邮件的需求时建议使用POP3协议
      • 单项通信协议(MUA <-- MDA)
        • 默认情况下,客户端将邮件从服务器上下载之后,服务器上就不会再存有被下载过后的邮件了(可以配置服务器,客户端都保存)
    • IMAP4(Internet Message Access Protocol 4)互联网消息访问协议
      • 默认端口:143
      • 适合多邮件客户端,双向同步协议(MUA <--> MDA)
        • 在不同平台上使用多个客户端都能收,比如PC、手机、平板上都有一个客户端连接相同的邮件服务器,在PC、手机、平板之中的某一个客户端上面操作都会同步给其他客户端
  • 其他邮箱访问方式
    • Web Mail
    • MAPI
      • 微软专有邮件协议
  • Fetchmail
    • 邮件服务器 <-- 邮件服务器(POP3 / IMAP)
    • 适用于没有稳定互联网连接的小公司
    • 从远程的 IMAP 和 POP 服务器上获得邮件后不是直接存入本地信箱,而是将邮件送入本地邮件系统进行再次投递
      • 既扮演客户端(从远程的 IMAP 和 POP 服务器上获得邮件),又扮演服务器(将下载得来的再次进行投递)

14.3 Postfix 简单部署和使用 {#143-postfix-简单部署和使用}

14.3.1 简单部署 {#1431-简单部署}

  1. 安装并配置DNS服务器

    1. 安装DNS服务器软件 ,命令:sudo apt install bind9

    2. 配置DNS服务器,启用转发器 ,命令:sudo vim /etc/bind/named.conf.options

      # 取消注释forwards配置项
      
      forwarders {
      	8.8.8.8;
      };
      
    3. **配置DNS服务器,创建自己的域,**命令:sudo vim /etc/bind/named.conf.local

      # 在其中创建自己的域
      
      zone "qq.com" {
      	type master;
      	file "/etc/bind/db.qq.com";
      };
      
    4. 配置DNS服务器,创建并编辑区域文件 ,命令:sudo cp /etc/bind/db.local /etc/bind/db.qq.com 通过复制默认已有的区域文件来创建新的区域文件,在复制出的新区域文件上修改,省的从头编写,然后编辑区域文件 ,命令:sudo vim /etc/bind/db.qq.com

      ;
      ; BIND data file for local loopback interface
      ;
      $TTL    604800
      @       IN      SOA     ns.qq.com. root.qq.com. (
                                    2         ; Serial
                               604800         ; Refresh
                                86400         ; Retry
                              2419200         ; Expire
                               604800 )       ; Negative Cache TTL
      ;
      @       IN      NS      ns
      @       IN      MX 5    mail
      ns      IN      A       192.168.2.247
      mail    IN      A       192.168.2.247
      pop     IN      A       192.168.2.247
      imap    IN      A       192.168.2.247
      smtp    IN      A       192.168.2.247
      @       IN      A       192.168.2.247
      
    5. 重启DNS服务,使配置生效 ,命令:sudo systemctl restart bind9.service

  2. 设置服务器的IP地址为静态IP地址

    1. 编辑服务器IP地址配置文件,配置静态IP地址 ,命令:sudo vim /etc/netplan/50-cloud-init.yaml 后面的文件名以一定相同,但是都是yaml为后缀名的文件

      network:
      	version: 2
      	ethernets:
      		ens33:
      			addresses: [192.168.2.247/24]
                  gateway4: 192.168.2.1
                  dhcp4: no
                  nameservers:
                  		search: [qq.com]
                  		addresses: [192.168.2.247]
                  optional: true
      
    2. 使网络配置生效 ,命令:sudo netplan apply

    3. 查看配置是否生效 ,命令:sudo networkctl status

  3. 修改主机名,容易分辨出这台机器是邮件服务器

    1. 编辑hostname文件,修改主机名 ,命令:sudo vim /etc/hostname 修改为自己想要的主机名,比如:mail.qq.com
    2. 编辑配置文件,允许修改主机名,Ubuntu18.04默认情况下是不允许修改主机名的,所有即使修改了/etc/hostname文件也不会生效,重启过后,又会变成之前的主机名了,所有要修改配置文件,允许修改主机名 ,命令:sudo vim /etc/cloud/cloud.cfg 修改配置项为truepreserve_hostname: true
    3. 重启计算机,使配置生效,重启过后,使用命令:hostname,查看当前主机名
  4. 安装并配置Postfix

    1. 安装Postfix ,命令:sudo apt install postfix

    2. 安装完成之后,Postfix会在系统中创建一个mail组账号,和postfix账号和组,只有将账号加入mail组中才会有收发邮件的功能

      • 默认使用的是本地域,也就是操作系统账号被作为邮箱账号,下一节的企业级邮件部署中使用的是虚拟域就可以任意创建账号而域操作系统账号无关

      • 命令:sudo usermod -aG mail $(whoami) 将当前账号加入到mail组

      • 命令:sudo usermod -aG mail Lw 将Lw账号加入到mail组

      • 命令:sudo useradd -m -G mail zs 创建zs账号,并加入到mail组

14.3.2 简单使用 {#1432-简单使用}

  1. 安装字符界面邮件客户端 ,命令:sudo apt install mailutils

  2. 安装完成之后,就有mail命令了

    • 发邮件(可以向互联网上发送邮件) ,例如:mail zs@qq.com

    • 收邮件
      • 可以收本机中别的账户(需要在mail组中)给我发送的邮件
        • 在/var/mail目录下查看,每个账号有对应的一个文件,使用cat命令查看即可
      • 不能够收互联网上发送的邮件,因为互联网上的邮件服务器无法找到此邮件服务器

14.4 企业级邮件系统部署 {#144-企业级邮件系统部署}

14.4.1 安装环境 {#1441-安装环境}

  • 配置DNS服务器和邮件服务器系统基本配置
    • 实际情况下是在已有的DNS服务器中配置邮件服务器的解析等,这里是演示情况就新安装一个DNS服务器并配置
    • 在DNS中为邮件服务器配置的不同的主机记录,实际中应解析到不同的真实服务器上,这里只是演示就全部解析到本机上了
  1. 安装并配置DNS服务器

    1. 安装DNS服务器软件 ,命令:sudo apt install bind9

    2. 配置DNS服务器,启用转发器 ,命令:sudo vim /etc/bind/named.conf.options

      # 取消注释forwards配置项
      
      forwarders {
      	8.8.8.8;
      };
      
    3. **配置DNS服务器,创建自己的域,**命令:sudo vim /etc/bind/named.conf.local

      # 在其中创建自己的域
      
      zone "qq.com" {
      	type master;
      	file "/etc/bind/db.qq.com";
      };
      
    4. 配置DNS服务器,创建并编辑区域文件 ,命令:sudo cp /etc/bind/db.local /etc/bind/db.qq.com 通过复制默认已有的区域文件来创建新的区域文件,在复制出的新区域文件上修改,省的从头编写,然后编辑区域文件 ,命令:sudo vim /etc/bind/db.qq.com

      ;
      ; BIND data file for local loopback interface
      ;
      $TTL    604800
      @       IN      SOA     ns.qq.com. root.qq.com. (
                                    2         ; Serial
                               604800         ; Refresh
                                86400         ; Retry
                              2419200         ; Expire
                               604800 )       ; Negative Cache TTL
      ;
      @       IN      NS      ns
      @       IN      MX 5    mail
      ns      IN      A       192.168.2.247
      mail    IN      A       192.168.2.247
      pop     IN      A       192.168.2.247
      imap    IN      A       192.168.2.247
      smtp    IN      A       192.168.2.247
      @       IN      A       192.168.2.247
      
    5. 重启DNS服务,使配置生效 ,命令:sudo systemctl restart bind9.service

  2. 设置服务器的IP地址为静态IP地址

    1. 编辑服务器IP地址配置文件,配置静态IP地址 ,命令:sudo vim /etc/netplan/50-cloud-init.yaml 后面的文件名以一定相同,但是都是yaml为后缀名的文件

      network:
      	version: 2
      	ethernets:
      		ens33:
      			addresses: [192.168.2.247/24]
                  gateway4: 192.168.2.1
                  dhcp4: no
                  nameservers:
                  		search: [qq.com]
                  		addresses: [192.168.2.247]
                  optional: true
      
    2. 使网络配置生效 ,命令:sudo netplan apply

    3. 查看配置是否生效 ,命令:sudo networkctl status

  3. 修改主机名,容易分辨出这台机器是邮件服务器

    1. 编辑hostname文件,修改主机名 ,命令:sudo vim /etc/hostname 修改为自己想要的主机名,比如:mail.qq.com
    2. 编辑配置文件,允许修改主机名,Ubuntu18.04默认情况下是不允许修改主机名的,所有即使修改了/etc/hostname文件也不会生效,重启过后,又会变成之前的主机名了,所有要修改配置文件,允许修改主机名 ,命令:sudo vim /etc/cloud/cloud.cfg 修改配置项为truepreserve_hostname: true
    3. 重启计算机,使配置生效,重启过后,使用命令:hostname,查看当前主机名

14.4.2 准备工作 {#1442-准备工作}

  • 需要安装的组件
    • Postfix:MTA
    • Dovecot:POP / IMAP 服务
    • SASL:身份认证
    • Postfixadmin:管理邮件、虚拟域、别名等的WEB应用
    • LEMP:Postfixadmin 依赖(LAMP也可以)
  • Postfix 的两种域
    • Local Domain:为本系统账号投递邮件(/etc/passwd),系统账号作为邮件账号
    • Virtual Domain(虚拟域):为非本系统账号投递邮件,系统账号不作为邮件账号,单独创建邮件账号

14.4.3 安装LEMP环境 {#1443-安装lemp环境}

  1. 安装并配置nginx

    1. 安装nginx ,命令:sudo apt install nginx
  2. 安装并配置mysql

    1. 安装mysql ,命令:sudo apt install mysql-server

    2. mysql基本安全加固 ,命令:sudo mysql_secure_installation

    3. 新安装好mysql之后,修改root身份认证方式为mysql_native_password ,使用sudo mysql进入mysql命令行,执行

      -- 修改root账号的身份认证方式为mysql_native_password,并设置密码为12345678
      alter user 'root'@'localhost' identified with mysql_native_password by '12345678';
      
      flush privileges;	-- 刷新权限
      
  3. 使Nginx支持PHP且PHP能够连接MySQL

    1. 安装相应的包,命令:sudo apt install php-fpm php-mysql

    2. 对php-fpm的PHP做基本的配置 ,命令:sudo vim /etc/php/7.2/fpm/php.ini

      cgi.fix_pathinfo=0
      date.timezone = Asia/Shanghai	# 设置时区
      
    3. 重启服务使配置生效 ,命令:sudo systemctl restart php7.2-fpm.service

  4. 检测LEMP环境是否配置成功

    1. 配置Nginx默认站点配置文件,让其支持PHP ,命令:/etc/nginx/sites-available/default

      # 修改其中的对php请求处理的配置项
      
      location ~ \.php$ {
      	include snippets/fastcgi-php.conf;	# 取消这行注释,让php在运行的过程中可以读取到相应的配置文件
      	fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; # 取消这行注释,将最后的 php7.0-fpm.sock 改为本机当前运行的php进程名称php7.2-fpm.sock
      }	
      
    2. 重启Nginx服务,使配置生效 ,命令:sudo systemctl restart nginx.service

    3. 在默认站点根目录**/var/www/html下创建 info.php**,里面写<?php phpinfo();?>

    4. 打开浏览器访问,http://ip/info.php,验证PHP是否配置成功

14.4.4 安装Postfixadmin {#1444-安装postfixadmin}

  1. 安装依赖软件包 ,命令:sudo apt install php-imap php-mbstring php7.2-imap php7.2-mbstring

  2. 去GitHub上下载Postfixadmin的源码 ,命令:sudo wget -P /opt https://github.com/postfixadmin/postfixadmin/archive/postfixadmin-3.2.tar.gz 将下载的源码文件方法哦/opt目录下(个人安装的应用一般都放到opt目录下)

  3. 解包下载的源码文件 ,命令:sudo tar xvf /opt/postfixadmin-3.2.tar.gz -C /opt

  4. 重命名解包得到的目录 ,命令:sudo mv /opt/postfixadmin-postfixadmin-3.2 /opt/postfixadmin

  5. 将postfixadmin目录下的public目录软链接到默然站点根目录下postfixadmin目录(或者新创建Nginx站点) ,命令:sudo ln -s /opt/postfixadmin/public/ /var/www/html/postfixadmin

  6. 为Postfixadmin创建给其使用的数据库和供其连接的账号,在mysql命令行中

    CREATE DATABASE postfix;	-- 创建数据库
    CREATE USER 'postfix'@'localhost' IDENTIFIED BY '12345678';	-- 创建账号
    GRANT ALL PRIVILEGES ON postfix.* TO 'postfix'@'localhost';	-- 赋予权限
    FLUSH PRIVILEGES;	-- 刷新权限
    
  7. 创建Postfixadmin连接数据库的配置文件

    1. 复制一份默认的配置文件 ,命令:sudo cp /opt/postfixadmin/config.inc.php /opt/postfixadmin/config.local.php

    2. 基于复制出来的配置文件上修改 ,命令:sudo vim /opt/postfixadmin/config.local.php

      // 修改其中的配置项
      
      $CONF['configured'] = true;	// 允许修改配置
      $CONF['default_language'] = 'cn';	// 语言环境修改为中文
      
      $CONF['database_type'] = 'mysqli';			// 要连接数据库服务器的类型
      $CONF['database_host'] = 'localhost';		// 要连接数据库服务器的地址
      $CONF['database_user'] = 'postfix';			// 要连接数据库服务器的账号
      $CONF['database_password'] = '12345678';	// 要连接数据库服务器的账号密码
      $CONF['database_name'] = 'postfix';			// 要连接数据库服务器的数据库名称
      
  8. 创建Postfixadmin安装过程中所需的临时目录

    1. 创建临时目录 ,命令:sudo mkdir /opt/postfixadmin/templates_c
    2. 修改临时目录权限为775 ,命令:sudo chmod 755 -R /opt/postfixadmin/templates_c
    3. 修改临时目录属主属组为www-data(www-data是专门运行WEB的账号的组) ,命令:sudo chown -R www-data:www-data /opt/postfixadmin/templates_c
  9. WEB安装阶段

    1. 浏览器访问,http://ip/postfixadmin/setup.php

    2. 设置Setup的密码,当操作管理员账号密码时需要此密码

    3. 将生成的Setup密码的hash设置为/opt/postfixadmin/config.local.php配置文件中$CONF['setup_password']项的值

      4-安装Postfixadmin-1

    4. 创建管理员账号

    5. 使用新增的管理员账号登录后台进行管理

    6. 创建域(按实际情况来)

    7. 然后就是创建邮箱,别名等操作了,就按实际情况来就可以了

14.4.5 安装邮件服务 {#1445-安装邮件服务}

  1. 安装基本组件并配置

    1. 安装postfix,支持postfix连接mysql,身份认证的组件 ,命令:sudo apt install postfix postfix-mysql sasl2-bin

    2. 配置身份认证sasl组件自动启动 ,命令:sudo vim /etc/default/saslauthd ,将配置文件中的START配置项改为yes,START=yes

    3. 重启sasl服务,使配置生效 ,命令:sudo systemctl restart saslauthd.service

  2. 创建邮箱存储目录,访问目录使用的账号和组账号

    • 因为现在使用的是虚拟域,所以要指定邮箱存储的位置,而且为了让虚拟域下所有的邮箱能够正常访问需要创建专用的用户账号和组账号
    1. 创建专用的组账号 ,命令:sudo groupadd -g 5000 vmail 创建了vmail这个组账号,gid设置为5000(设置成其他也可以)
    2. 创建虚拟域下存储邮箱的目录 ,命令:sudo mkdir -p /var/mail/vmail 创建了vmail这个目录
    3. 创建专用的用户账号 ,命令:sudo useradd -u 5000 vmail -g vmail -s /usr/sbin/nologin -d /var/mail/vmail 创建了vmail用户账号,指定uid为5000(设置其他也可以),指定此账号加入vmail组,禁用了操作系统本地登录权限,设置主目录为/var/mail/vmail
    4. 修改邮箱存储目录vmail属主与属组为vmail账号和组 ,命令:sudo chown -R vmail:vmail /var/mail/vmail vmail用户账号需要访问/var/mail/vmail目录下所有的内容,故vmail账号等同于虚拟域邮件服务的运行访问账号,所以vmail账号必须对/var/mail/vmail目录有所有权
  3. postfix数据库相关配置

    1. 创建配置文件存放目录,将sql相关的配置文件都放到这个目录中,方便管理 ,命令:sudo mkdir -p /etc/postfix/sql

    2. 查询虚拟域配置文件

      1. 创建并编辑配置文件 ,命令:sudo vim /etc/postfix/sql/mysql_virtual_domains_maps.cf 这个配置文件的作用就是去数据库中查找虚拟域,在其中添加

        user = postfix			# 连接数据库的账号
        password = 12345678		# 连接数据库的账号密码
        hosts = 127.0.0.1		# 数据库服务器的IP地址
        dbname = postfix		# 连接数据库的库的名称
        query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'	# 使用sql查找语句,来查找虚拟域名,%s的作用:查询时指定的虚拟域名称会将这个%s替换掉,这样就是一个正确的sql查询语句
        
      2. 使配置文件生效并验证

        1. 使配置文件生效 ,命令:sudo postconf -e virtual_mailbox_domains=mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf 表示虚拟邮箱域(virtual_mailbox_domains)从mysql服务器中去查,使用/etc/postfix/sql/mysql_virtual_domains_maps.cf这个配置文件去查,也就是让postfix读取/etc/postfix/sql/mysql_virtual_domains_maps.cf这个配置文件中的配置,使用其中的配置去查找虚拟域
        2. 验证配置是否生效 ,命令:sudo postmap -q qq.com mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf 查询qq.com这个虚拟域,如果查出来则表示配置没有问题(前提是在postfixadmin中已经创建了qq.com虚拟域)
    3. 查询邮箱配置文件

      1. 创建并编辑配置文件 ,命令:sudo vim /etc/postfix/sql/mysql_virtual_mailbox_maps.cf 这个配置文件的作用就是去数据库中查找邮箱,在其中添加

        user = postfix			# 连接数据库的账号
        password = 12345678		# 连接数据库的账号密码
        hosts = 127.0.0.1		# 数据库服务器的IP地址
        dbname = postfix		# 连接数据库的库的名称
        query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'	# 使用sql查找语句,来查找邮箱,%s的作用:查询时指定的邮箱名称会将这个%s替换掉,这样就是一个正确的sql查询语句了
        
      2. 使配置文件生效并验证

        1. 使配置文件生效 ,命令:sudo postconf -e virtual_mailbox_maps=mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf 表示邮箱查找(virtual_mailbox_maps)从mysql服务器中去查,使用/etc/postfix/sql/mysql_virtual_mailbox_maps.cf这个配置文件去查,也就是让postfix读取/etc/postfix/sql/mysql_virtual_mailbox_maps.cf这个配置文件中的配置,使用其中的配置去查找邮箱
        2. 验证配置是否生效 ,命令:sudo postmap -q tom@qq.com mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf 查询tom@qq.com这个邮箱,如果查出来则表示配置没有问题(前提是在postfixadmin中已经创建了tom@qq.com这个邮箱)
    4. 查询别名配置文件

      1. 创建并编辑配置文件 ,命令:sudo vim /etc/postfix/sql/mysql_virtual_alias_maps.cf 这个配置文件的作用就是去数据库中查找邮箱,在其中添加

        user = postfix			# 连接数据库的账号
        password = 12345678		# 连接数据库的账号密码
        hosts = 127.0.0.1		# 数据库服务器的IP地址
        dbname = postfix		# 连接数据库的库的名称
        query = SELECT goto FROM alias WHERE address='%s' AND active = '1'	# 使用sql查找语句,来查找邮箱,%s的作用:查询时指定的别名会将这个%s替换掉,这样就是一个正确的sql查询语句了
        
      2. 使配置文件生效并验证

        1. 使配置文件生效 ,命令:sudo postconf -e virtual_alias_maps=mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf 表示别名查找(virtual_alias_maps)从mysql服务器中去查,使用/etc/postfix/sql/mysql_virtual_alias_maps.cf这个配置文件去查,也就是让postfix读取/etc/postfix/sql/mysql_virtual_alias_maps.cf这个配置文件中的配置,使用其中的配置去查找邮箱
        2. 验证配置是否生效 ,命令:sudo postmap -q abuse@qq.com mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf 查询abuse@qq.com这个别名,如果查出来这个别名转到的真实邮箱则表示配置没有问题(前提是在postfixadmin中已经创建了abuse@qq.com这个别名)
    5. 将创建的三个配置文件属组改为postfix,以免发生权限上的问题 ,命令:sudo chgrp postfix /etc/postfix/sql/mysql_*.cf

  4. 配置postfix身份认证

    1. 启用 SASL 强制 Postfix 发邮件使用 Dovecot 进行身份验证,编辑postfix主配置文件 ,命令:sudo vim /etc/postfix/main.cf 在配置文件最底部新增

      smtpd_sasl_type = dovecot		# 配置sasl身份认证类型是dovecot(下一步会安装dovecot)
      smtpd_sasl_path = private/auth	# 指定sasl的路径
      smtpd_sasl_auth_enable = yes	# 启用身份认证功能
      smtpd_sasl_security_options = noanonymous	# 身份认证安全选项,禁止匿名账户使用
      smtpd_sasl_local_domain = $myhostname		
      smtpd_tls_security_level = may	# 身份认证过程使用tls(ssl的升级版本)加密,may表示可以,最终选择权在用户手中,用户可以选择是否要tls加密,因为有的邮件客户端不支持tls加密(这里是设置允许客户端是否可以选择tls加密,服务端设置tls加密在master.cf配置文件中设置)
      smtpd_tls_auth_only = no		# 不只用tls加密
      smtpd_recipient_restrictions = permit_mynetworks permit_sasl_authenticatedreject_unauth_destination	# 限制收件人的范围,没有身份认证的就限制使用,允许经过身份认证的人来使用
      
      # 你可以选择tls加密使用的证书,可以申请一个商业的加密证书,这里就使用了自签名证书了,在此配置项中修改
      smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
      smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
      

    2. 启用SMTP安全(加密)端口和身份认证相关配置,编辑postfix工作过程配置文件命令:sudo vim /etc/postfix/master.cf 修改和新增其中的配置内容

      # 取消注释
      submission inet n       -       y       -       -       smtpd
      -o syslog_name=postfix/submission	# 日志记录配置
      -o smtpd_tls_security_level=encrypt	# 启用服务端tls加密
      -o smtpd_sasl_auth_enable=yes		# 启用sasl身份认证
      -o milter_macro_daemon_name=ORIGINATING
      -o smtpd_client_restrictions=permit_sasl_authenticated,reject	# 手动添加此行
      
      # 取消注释
      smtps     inet  n       -       y       -       -       smtpd
      -o syslog_name=postfix/smtps		# 日志记录配置
      -o smtpd_tls_wrappermode=yes		# 启用服务端tls加密
      -o smtpd_sasl_auth_enable=yes		# 启用sasl身份认证
      -o milter_macro_daemon_name=ORIGINATING
      -o smtpd_client_restrictions=permit_sasl_authenticated,reject	# 手动添加此行
      

    3. 验证配置是否正确 ,命令:sudo postconf -n

    4. 重启服务,使配置生效 ,命令:sudo systemctl restart postfix.service

  5. 安装并配置dovecot及必要组件

    1. 安装dovecot及必要组件 ,命令:sudo apt install dovecot-imapd dovecot-mysql dovecot-managesieved dovecot-pop3d

      | 组件 | 作用 | |----------------------|-----------------------------------| | dovecot | 提供IMAP服务,POP3服务等 | | dovecot-mysql | dovecot连接mysql的功能模块 | | dovecot-managesieved | Sieve组件,自动创建相应文件夹,并将邮件自动放入指定用户文件夹 |

    2. 编辑身份认证相关配置文件 ,命令:sudo vim /etc/dovecot/conf.d/10-auth.conf 修改其中的内容

      auth_mechanisms = plain login	# 在登录时使用明文的身份认证机制
      # !include auth-system.conf.ext	# 注释掉此行,这行表示用系统的账号作为身份认证的数据,而现在是要使用数据库存储的邮箱数据作为身份认证数据
      !include auth-sql.conf.ext		# 取消此行注释,读取数据库中的数据来做身份认证
      
    3. 编辑数据库相关配置文件 ,命令:sudo vim /etc/dovecot/conf.d/auth-sql.conf.ext 修改其中的内容

      # 密码数据库配置
      passdb {		
        driver = sql	# 使用sql的驱动
      
        # Path for SQL configuration file, see example-config/dovecot-sql.conf.ext
        args = /etc/dovecot/dovecot-sql.conf.ext	# 连接数据库使用这个配置文件中的内容(下一步会配置这个配置文件中的内容)
      }
      
      # 注销默认的用户数据库配置
      #userdb {
      #  driver = sql
      #  args = /etc/dovecot/dovecot-sql.conf.ext
      #}
      
      # 启用这个用户数据库配置并修改
      userdb {
        driver = static
        args = uid=vmail gid=vmail home=/var/mail/vmail/%d/%n	# 邮箱存储主目录指向/var/mail/vmail/%d/%n,%d指的是每个域的目录,%n指的是域中每个邮箱账号的目录
      }
      
    4. 配置数据库连接的配置文件 ,命令:sudo vim /etc/dovecot/dovecot-sql.conf.ext 在配置文件底部新增

      driver = mysql	# 使用mysql数据库驱动
      connect = host=127.0.0.1 dbname=postfix user=postfix password=12345678
      password_query = SELECT username,domain,password FROM mailbox WHERE username='%u';
      default_pass_scheme = MD5-CRYPT	# 密码的加密方式
      
    5. 指定邮箱的存储位置,让dovecot知道收到的邮件存到哪个位置 ,命令:sudo vim /etc/dovecot/conf.d/10-mail.conf 修改配置文件内容

      # mail_location = mbox:~/mail:INBOX=/var/mail/%u	# 默认的配置是mbox,将邮件存到一个文件中,这样是有风险和隐患的,将这个配置修改为下面这一行
      mail_location = maildir:/var/mail/vmail/%d/%n/Maildir	# 指定了邮件存储位置,并将邮件存储方式改为maildir
      
      mail_privileged_group = mail	# 修改组账号为mail组账号(postfix安装过程中创建的mail组账号,只有将账号加入mail组中才会有收发邮件的功能)
      
    6. 配置服务的连接 ,命令:sudo vim /etc/dovecot/conf.d/10-master.conf 修改和新增配置文件内容

      service auth {
        unix_listener auth-userdb {
          mode = 0600		# 出于安全的考虑,将默认文件权限改为0600
          user = vmail	# 操作使用的账号,配置之前专门创建的账号
          group = vmail	# 操作使用的组,配置之前专门创建的组账号
        }
      
        # Postfix smtp-auth
        unix_listener /var/spool/postfix/private/auth {
          mode = 0660		# 出于安全的考虑,将默认文件权限改为0600
          user = postfix	# 新增,认证使用的账号
          group = postfix	# 新增,认证使用的组账号
        }
      
        # Auth process is run as this user.
        user = dovecot	# 使用dovecot用户账号运行身份认证访问
      }
      
    7. 修改配置文件 ,命令:sudo vim /etc/dovecot/conf.d/15-lda.conf 修改和新增配置文件内容

      protocol lda {
        # Space separated list of plugins to load (default is global mail_plugins).
        mail_plugins = $mail_plugins sieve	# 取消此行注释,并将sieve插件加到此行后面,是sieve插件生效
      }
      
    8. 更改配置文件属组,因为使用专门创建的vmail来运行dovecot,运行过程中需要有权限读取这个配置文件 ,命令:sudo chgrp vmail /etc/dovecot/dovecot.conf

    9. 重启dovecot服务,使配置生效 ,命令:sudo systemctl restart dovecot.service

  6. 集成 Postfix 和 Dovecot

    1. 编辑postfix运行过程中相关的配置文件 ,命令:sudo vim /etc/postfix/master.cf 在底部新增

      dovecot   unix  -       n       n       -       -       pipe
        flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${user}@${nexthop}	# 格式很重要,前面要空两格,空两格,空两格......
      
    2. 编辑postfix主配置文件 ,命令:sudo vim /etc/postfix/main.cf 在底部新增

      virtual_transport = dovecot	
      dovecot_destination_recipient_limit = 1	# dovecot目标收件人限制为1
      
    3. 重启postfix服务,使配置生效 ,命令:sudo systemctl restart postfix.service

14.4.6 安装WEB Mail {#1446-安装web-mail}

  • 简介

    • 各大邮件服务商全部提供 WEB Mail
    • 基于浏览器的统一使用体验(无需配置客户端)
    • Roundcube 非常流行且稳定的 WEB Mail 应用
  • 安装

    1. 安装依赖包 ,命令:sudo apt install php-dompdf php7.2-intl php-imagick php7.2-ldap php7.2-xml

    2. 到GitHub下载Roundcube源码 ,命令:wget https://github.com/roundcube/roundcubemail/releases/download/1.3.6/roundcubemail-1.3.6-complete.tar.gz

    3. 解包下载的源码文件 ,命令:tar xvf roundcubemail-1.3.6-complete.tar.gz

    4. 将解包得到的目录移到站点根目录下,并重命名(各方面都方便一点) ,命令:sudo mv roundcubemail-1.3.6 /var/www/html/webmail

    5. 将重命名的webmail数主和属组改为www-data ,命令:chown -R www-data:www-data /var/www/html/webmail/

    6. 将临时目录和日志目录设置大一点的权限 ,命令:sudo chmod 755 /var/www/html/webmail/temp/ /var/www/html/webmail/logs/

    7. 创建给Roundcube使用的数据库,数据库账号

      -- 需要创建两个数据库
      CREATE DATABASE roundcubedb;	-- 创建数据库
      CREATE DATABASE roundcubemail;	-- 创建数据库
      
      CREATE USER 'roundcube'@'localhost' IDENTIFIED BY '12345678';	-- 创建账号
      
      GRANT ALL PRIVILEGES ON roundcubedb.* to 'roundcube'@'localhost';	-- 赋予权限
      GRANT ALL PRIVILEGES ON roundcubemail.* to 'roundcube'@'localhost';	-- 赋予权限
      
      FLUSH PRIVILEGES;	--刷新权限
      
    8. 导入数据库数据,Roundcube在解包得到的目录中有一个SQL目录,里面存放这不同数据库类型的初始化数据的sql语句,将对应的sql文件中的数据导入到对应的数据库中即可 ,命令:mysql -u roundcube -p roundcubedb < /var/www/html/webmail/SQL/mysql.initial.sql

    9. 配置站点文件 ,命令:sudo vim /etc/nginx/sites-available/default 在server配置段中找个空白的地方添加上就行了

      location /webmail {
      	root /var/www/html;
      	index index.php;
      	location ~ ^/webmail/(.+\.php)$ {
              root /var/www/html;
              try_files $uri =404;
              fastcgi_index index.php;
              fastcgi_pass unix:/run/php/php7.2-fpm.sock;
              fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              include /etc/nginx/fastcgi_params;
      	}
          location ~ ^/webmail/(README|INSTALL|LICENSE|CHANGELOG|UPGRADING)$ {
                  deny all;
          }
          location ~ ^/webmail/(bin|SQL|config|temp|logs)/ {
                  deny all;
          }
      }
      
    10. 重启Nginx服务,使配置生效 ,命令:sudo systemctl restart nginx.service

    11. WEB安装阶段,浏览器访问:http://ip/webmail/installer

      1. 环境检查

      2. 配置阶段,有很多配置(大多不用修改),这里只提供一些基本配置,实际中需要什么配置什么即可

      3. 检测配置阶段

第 15 章 监控 {#第-15-章-监控}

15.1 监控系统介绍 {#151-监控系统介绍}

15.1.1 为什么要用监控系统 {#1511-为什么要用监控系统}

  • 规模带来的挑战
    • 每当系统规模扩大10倍,原有的技术栈则需要替代
    • 更多系统、设备、应用的数量,不同的部署地点、不同的业务需求
    • 系统问题不能及时得到反馈,响应处理不及时(被动响应)设备服务间存在复杂的依赖关系,问题定位困难(分层带来的困扰)
      • 网络问题造成应用无法访问
      • 数据库问题造成应用无法访问
      • 资源抢占造成后台进程被系统杀掉
    • 来自用户的问题反馈通常存在误导因素
    • 问题出现前的性能指标预示着问题即将发生
    • 系统缺乏统一监控告警机制,失控
    • 统一的监控系统,自动告警、问题处理

15.1.2 常用监控系统 {#1512-常用监控系统}

  • 周期检查系统、服务是否可用
  • Nagios(开源免费)
  • Zabbix(开源免费)
  • Manageengine(商业收费)
  • Solarwind(商业收费)

15.1.3 监控技术 {#1513-监控技术}

  • 基于客户端
    • 适用于通用操作系统
  • 在要监控的机器上安装监控系统的客户端程序,由客户端程序检测这台机器运行状态并将检测结果返回给监控系统服务器,服务器收到结果后再根据结果做相应的操作
  • 基于SNMP协议 (简单网络管理协议)
    • 普遍适用、硬件设备
    • 私有的协议扩展

15.2 Nagios {#152-nagios}

15.2.1 简介 {#1521-简介}

  • nagios是开源的系统监视工具(core 开源免费、xi 商业收费)
    • 自动监视系统运行状态
    • 发现问题及时通知相关人
    • 支持客户端和SNMP兼容设备
  • 两类监控对象
    • Host:物理的、虚拟的、网络设备、打印机等(可分组)
    • Service:系统功能(系统服务、资源占用CPU、内存、存储)
    • Service 至少关联到一个 Host
  • 检查结果的4中状态
    • Ok 没有问题
    • Warning 警告,可能有问题
    • Critical 严重,问题已经发生了
    • Unknown 无法知道状态
    • 具体的性能指需定义为以上状态
  • 基于插件的系统框架
    • Nagios 将要检查什么,以及warning、critical的标准交给插件
    • 所有检查工作由插件完成,并分析检查结果
    • 内建插件主要由 C 语言开发(编译安装)
    • 不支持的检查功能可自行开发插件(支持所有语言)
  • 清晰的对象定义系统
    • Commands:插件之上的抽象层,将类似的操作分组处理
    • Time periods:应该或不应该执行监控操作的时间跨度
      • 在某个时间段内,不对某些个对象和下面的依赖进行监控,比如:凌晨1-3点要更换交换机,让监控系统不对交换机及其交换机下连的机器做监控
    • Hosts/Groups:一个或是一组主机(一个主机可以属于多个组)
    • Services:主机上需要监视的具体功能和资源(CPU、存储、WEB服务)
    • Contacts/Groups:联系人
    • Notifications:不同等级事件、时间通知谁什么内容
      • 何时以何种方式通知谁具体什么信息
      • 不是严格意义的对象,其他对象的结合
    • Escalations:通知升级,告警持续一定时间后升级
  • Nagios是一个依赖系统
    • 系统和服务依赖网络设备
    • 服务之间互相依赖,被依赖的服务故障时,依赖它的服务不再检查和告警
  • 计划宕机
    • 维护性宕机调度时nagios不发告警(包含依赖)
    • 也可以通知计划宕机维护
  • 软硬状态
    • 为避免随机和临时性故障告警,Nagios 状态区分软硬
    • 当前与之前检测状态不同时故障为软状态,相同则为硬状态(重试次数)

15.2.2 安装 {#1522-安装}

  • Ubuntu 官方库包含 Nagios 3.X 版本

    • 安装命令:sudo apt install nagios3 nagios-plugins
      • nagios3 软件包
      • nagios-plugins 实现同时监视本机的功能
      • 不仅会安装nagios还会安装WEB服务器、PHP、MySQL等相关组件,提供WEB访问方式
    • 官方最新版本 4.4.2(手动编译安装)
    • 提供 WEB 访问方式(历史状态)
  • 手动编译安装

    • 需要:C编译期、C语言开发库、OpenSSL实现WEB加密访问、MySQL存储历史数据、PHP、SNMP、图形组件等
    1. 安装相应组件 ,命令:sudo apt -y install wget gcc make binutils cpp libpq-dev libmysqlclient-dev libssl1.0.0 libssl-dev pkg-config libgd-dev libgd-tools perl libperl-dev libnet-snmp-perl snmp apache2 apache2-utils libapache2-mod-php unzip tar gzip php php-gd

    2. 创建目录结构

      • 命令:sudo mkdir /opt/nagios 二进制、插件,程序安装目录
      • 命令:sudo mkdir /var/nagios 状态数据(历史数据)
      • 命令:sudo mkdir /etc/nagios 配置文件(安装过程生成)
    3. 创建用户和组账号

      1. 命令:sudo groupadd nagios Nagios后台进程运行账号使用的组
      2. 命令:sudo groupadd nagioscmd WEB进程与Nagios后台进程通信使用的组
      3. 命令:sudo useradd -g nagios -G nagioscmd -d /opt/nagios nagios 创建nagios帐号,指定主目录为/opt/nagios,主组为nagios,加入额外的组为nagioscmd
      4. 命令:sudo usermod -G nagioscmd www-data WEB服务需与 nagios 通信,将www-data加入到nagioscmd组
    4. 设置文件系统权限

      • 将新创建的三个目录属主和数组都改为nagios,命令:sudo chown nagios:nagios /opt/nagios /etc/nagios /var/nagios
    5. 下载源码

      1. 下载主程序源码 ,命令:wget https://assets.nagios.com/downloads/nagioscore/releases/nagios-4.4.2.tar.gz
      2. 解包主程序源码 ,命令:tar -xzf nagios-4.4.2.tar.gz
      3. 下载插件源码 ,命令:wget https://nagios-plugins.org/download/nagios-plugins-2.2.1.tar.gz
      4. 解包插件源码 ,命令:tar -xzf nagios-plugins-2.2.1.tar.gz
    6. 编译安装主程序

      1. 进入Nagios主程序目录中 ,命令:cd nagios-4.4.2/

      2. 编译前配置 ,命令:sudo ./configure --prefix=/opt/nagios --sysconfdir=/etc/nagios --localstatedir=/var/nagios --libexecdir=/opt/nagios/plugins --with-command-group=nagioscmd

        • --prefix=/opt/nagios 指定程序(二进制)将来安装的位置
        • --sysconfdir=/etc/nagios 指定配置文件存放位置
        • --localstatedir=/var/nagios 指定历史状态数据存放位置
        • --libexecdir=/opt/nagios/plugins 指定插件存放位置
        • --with-command-group=nagioscmd 指定command命令执行的组账号(指定为用来和WEB通信的组账号)
      3. 编译 ,命令:sudo make all

      4. 安装主程序、CGI、HTML等 ,命令:sudo make install

      5. 安装扩展命令 ,命令:sudo make install-commandmode

      6. 安装例子配置文件 ,命令:sudo make install-config

      7. 创建系统服务文件 ,命令:sudo make install-init

      8. 验证配置文件 ,命令:sudo su -c '/opt/nagios/bin/nagios -v /etc/nagios/nagios.cfg 使用nagios账号检查nagios.cfg例子配置文件是否正常

    7. 编译安装插件(在需要被监视的机器上安装,安装在本机上也会监视本机)

      1. 进入到插件源码目录 ,命令:cd nagios-plugins-2.2.1/

      2. 编译前配置 ,命令:sudo sh configure --prefix=/opt/nagios --sysconfdir=/etc/nagios --localstatedir=/var/nagios --libexecdir=/opt/nagios/plugins

        • --prefix=/opt/nagios 指定程序(二进制)将来安装的位置
        • --sysconfdir=/etc/nagios 指定配置文件存放位置
        • --localstatedir=/var/nagios 指定历史状态数据存放位置
        • --libexecdir=/opt/nagios/plugins 指定插件存放位置
      3. 编译 ,命令:sudo make all

      4. 安装 ,命令:sudo make install

    8. 给Nagios创建WEB站点

      1. 创建站点配置文件 ,命令:sudo vim /etc/apache2/sites-available/nagios.conf 配置内容如下

        ScriptAlias /nagios/cgi-bin /opt/nagios/sbin
        Alias /nagios /opt/nagios/share
        <Location "/nagios">
            AuthName "Nagios Access"
            AuthType Basic
            AuthUserFile /etc/nagios/htpasswd.users
            require valid-user
        </Location>
        <Directory "/opt/nagios/share">
            AllowOverride None
            Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
            Require all granted
            Order allow,deny
            Allow from all
        </Directory>
        <Directory "/opt/nagios/sbin">
            AllowOverride None
            Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
            Require all granted
            Order allow,deny
            Allow from all
        </Directory>
        
      2. 启用Nagios站点 ,命令:sudo a2ensite nagios.conf

      3. 启用Nagios需要的cgi模块 ,命令:sudo a2enmod cgi

      4. 启用Nagios需要的基本身份认证模块 ,命令:sudo a2enmod auth_basic

      5. 创建基本身份认证所需的账号和密码 ,命令:sudo htpasswd -c /etc/nagios/htpasswd.users nagiosadmin

        • 使用htpasswd创建账号nagiosadmin,密码保存到/etc/nagios/htpasswd.users

      6. 重启Apache服务,使配置生效 ,命令:sudo systemctl restart apache2.service

    9. 重启Nagios服务,使配置生效 ,命令:sudo systemctl restart nagios.service

    10. 使用浏览器访问:http://ip/nagios,查看安装是否成功,登录的账号密码就是上面新创建的nagiosadmin账号和其对应的密码

15.2.3 配置01 {#1523-配置01}

  • 配置文件

    • /etc/nagios/ 所有Nagios配置文件都在此目录下

      • /etc/nagios/nagios.cfg 主配置文件(启动时加载,其他配置的入口)

        • cfg_file 单个的对象定义文件,注释掉以这个开头的行,使用对象定义文件目录,这样结构清晰(每一小类为单独的配置文件),方便管理

        • cfg_dir 对象定义文件目录(所有.cfg文件及子目录),将每一大类的配置文件放到相关的目录下

          # Nagios会读取下面指定目录下的cfg文件和子目录下的cfg文件以及子目录的子目录下的等子目录
          
          cfg_dir=/etc/nagios/commands		# 所有的命令放到此目录下,包含两类命令:第一类监视相关的命令,第二类是发现了问题如何处置(发邮件、发信息、重启服务等),监视不同的系统可以在此目录下创建不同的子目录,比如支付系统单独创建一个pay子目录,销售系统单独创建一sales目录,将配置文件放到各自对应的子目录下面去,这样假如想修改某个(些)主机的监视命令时,可以通过目录结构就定位到准确的位置
          cfg_dir=/etc/nagios/contacts		# 联系人
          cfg_dir=/etc/nagios/contactgroups	# 联系人分组
          cfg_dir=/etc/nagios/hosts			# 主机,一个主机至少要对应一个服务
          cfg_dir=/etc/nagios/hostgroups		# 主机分组
          cfg_dir=/etc/nagios/services		# 服务,除了包含http、ftp、smb、ssh等服务外还包含像CPU使用量、内存使用量、存储空间使用量、系统负载等系统性能参数,在Nagios中这些都包含在服务中
          cfg_dir=/etc/nagios/servicegroups	# 服务分组
          cfg_dir=/etc/nagios/templates		# 模板,定义其他配置的模板,最主要的就是为host和services定义模板,针对这两种对象来定义好相应的模板,基于这个模板来创建host和services,这样会提高大大效率
          cfg_dir=/etc/nagios/timeperiods		# 时间范围,一般会定义这几个:7*24小时定义一个时间范围对象,工作时间(周一到周五早9晚5)定义一个时间范围对象,业余时间(不再发告警等),定义一个系统维护时间(不发告警)
          
        • resource_file 资源文件,宏(定义全局变量等)

      • 分类存储 类型、、功能、业务(易于统一开关)

  • 创建目录结构

    1. 命令:cd /etc/nagios 进入nagios配置文件目录

    2. 命令:sudo mkdir commands timeperiods contacts contactgroups hosts hostgroups services servicegroups

  • Nagios监控

15.2.4 配置02 {#1524-配置02}

    • 宏的好处

      # 定义一个主机
      define host{
      	host_name		somemachine			# 取个名字,方便识别
      	address			10.0.0.1			# 主机的地址
      	check_command	check-host-ssh	# 检查命令,使用 check_command 这个属性指定在command配置文件中事前就定义好了的名字叫 check-host-ssh 中配置的命令来检查当前主机
      }
      
      # 定义命令
      define command{
      	command_name	check-host-ssh	# 命令的名称
      	command_line	$USER1$/check_ssh -H $HOSTADDRESS$	# 具体执行的命令
      }
      # $USER1$/check_ssh -H $HOSTADDRESS$ 对应的命令就是 /opt/nagios/plugins/check_ssh -H 10.0.0.1 意思是:执行 /opt/nagios/plugins/check_ssh 命令,-H参数是指定要检查主机的IP地址
      
      # $USER1$ 这个宏指的是一个路径,这个路径就是Nagios插件所在目录,这里是/opt/nagios/plugins
      # $HOSTADDRESS$ 这个宏就是host对象中定义的address属性对应的值,每一个host对象都有自己的address属性和值,也就是都有自己的对应 $HOSTADDRESS$ 宏,故虽然这个宏的名字都是一样的,但这个宏对应的内容却是每个host对象中的address属性中设置的地址(例如:10.0.0.1)
      
      # 比如定义了两个host对象,address属性的值分别是10.0.0.1和10.0.0.2,都使用了check-host-ssh这个命令,因为他们的address属性的值不同,对应的 $HOSTADDRESS$ 宏的内容分别就是10.0.0.1和10.0.0.2,$USER1$/check_ssh -H $HOSTADDRESS$ 这个最终对应的命令就是 /opt/nagios/plugins/check_ssh -H 10.0.0.1 和 /opt/nagios/plugins/check_ssh -H 10.0.0.2,这样只需在host配置中指定check_command属性的值为check-host-ssh就可以了,而不需要更改命令的内容,因为它会根据不同的host取相对应的IP地址
      
    • 常用内建宏(全局变量)

    • 读取其他对象的宏

      # 内建宏通常都会对当前操作的对象(host、services等)进行应用,但是宏的使用是很灵活的
      # 你可以在操作当前这个对象的状态下引用其他的对象的宏,在当前对象的上下文使用
      
      # 比如说,当前操作的主机对象正常的邮件联系人应该是tom,现在想临时的将告警邮件联系人改为jdoe,就使用下面的宏
      $CONTACTEMAIL:jdoe$		# jdoe的邮件地址(非当前联系人)
      # 如果使用 $CONTACTEMAIL$ 这个宏,那么就会发给默认的邮件联系人tom
      
    • 自定义宏(对象属性字段)

      # 自定义宏用下划线开头
      _ZDYH			# 自定义一个对象的属性
      $_HOSTZDYH$		# 针对自定义的 _ZDYH 属性Nagios会自动生成一个宏,名称就是前面那个
      
      __ZDYH			# 自定义一个对象的属性
      $_HOST_ZDYH$	# 针对自定义的 __ZDYH 属性Nagios会自动生成一个宏,名称就是前面那个
      
      # 例如
      define host{
          host_name		somemachine
          address			10.0.0.1
          _MAC			12:12:12:12:12:12	# 自定义属性
          check_command	check-host-by-mac
      }
      
      define command{
          command_name	check-host-by-mac
          command_line	$USER1$/check_hostmac -H $HOSTADDRESS$ -m $_HOSTMAC$
      }
      # $自定义属性 _MAC 对应的宏:$_HOSTMAC$
      
  • 资源文件权限

    • 改变资源文件权限 ,命令:sudo chmod 600 /etc/nagios/resource.cfg 只允许属主对其有权限
    • 资源文件中可以定义 USER1 --- USER256 一共256个宏
    • 可以将一些机密的信息放到此文件中,当要用的时候,通过变量来调用
    • 内涵机密信息,应避免被WEB服务读取内容
  • host配置

    短名				# short name
    描述名				# description name
    地址/主机名
    何时以及如何监视
    故障时的联系人
    检查频率/重试次数
    如何发出告警
    ...
    
    # 必须项:
    #	host_name
    #	alias
    #	address
    #	max_check_attempts
    #	check_period
    #	contact_groups 或 contact
    #	notification_interval
    #	notification_period
    
    # 例如
    define host{
    	host_name				linuxbox1				# 短名,不可以与其他host定义的,host_name同名
    	hostgroups				linuxservers			# 加入主机组,可以加入多个主机组,用逗号分隔,两种方式:一是创建host时就指定加入主机组,二是先创建主机组,然后在创建的主机组中加入host
    	alias					Linux Server 01			# 描述名
    	address					10.0.2.15				# 地址,可以指定多个IP地址用逗号分隔,也可以使用域名,比如:abc.lab.com
    	check_command			check-host-alive		# 检查的命令,command配置文件中对应的配置项
    	check_interval			10						# 分钟,每10分钟检查一次
    	retry_interval			1						# 分钟,重试每1分钟检查一次,比如上一次检查目标没有答复,那么就每隔1分钟检查一次而不是10分钟,直到目标给了答复再10分钟检查一次
    	max_check_attempts		3						# 硬装态才告警,连续重试检查3次都出现问题,就将软状态改为硬状态
    	check_period			24*7					# 什么时间段检查
    	contact_groups			linux-admins			# 指定出现问题联系人组,或contact
    	notification_interval	30						# 分钟,如果问题没解决的话,每隔30分钟发一次告警
    	notification_period		24*7					# 什么时间段才可以发告警
    	notification_options	d,u,r					# 何种状态警告
            # d:DOWN			系统宕机
            # u:UNREACHABLE		不可达(一般都是服务器上连的网络设备,交换机、路由器等出现故障,导致连接不上服务器)
            # r:Recovery(UP)	从DOWN又恢复正常了
            # f:starts and stops flapping			在 d 和 r 之间来回摆动,一会好一会不好
            # s:scheduled downtime starts or ends	计划停机时间开始或结束,比如计划今天凌晨1点到3点对系统进行维护
    	parents					SW01					# 依赖(通常为交换机/路由器),当依赖出现故障了也就不再监控这台服务器了,因为如果交换机出现了故障都连不上这台机器了,再对这台机器告警也没有意义
    }
    

  • Host Group

    define hostgroup{
            hostgroup_name		linux-servers		# 短名,不可以和其他的组短名重复
            alias				linux servers		# 别名
            members				server01,server02	# 将server01和server02两个host加入此组
            hostgroup_members	group01,group02		# 将group01和group02两个组也加入到此组
    }
    
  • Service

    • 简介

      • NFS、FTP服务、存储空间、CPU 负载等
      • Service 永远绑定于一个运行状态的 HOST
      • 每个 HOST 至少要定义一个 Service
      • 通过唯一的描述名标识
      • 定义何时、如何进行检查(running)
      • 定义告警方式
      • 文件命名 /etc/nagios/services/host-service.cfg
    • 配置

      # 必须项:
      #	check_period
      #	max_check_attempts
      #	notification_interval
      #	notification_period
      #	contact_groups 或 contact
      
      define service{
      	host_name				localhost,srv1	# 要绑定的host,也可以用hostgroup_name绑定组
      	service_description		www				# 服务描述名,此service的唯一标识,不可以与其他service同名
          check_command			check_http		# 指定command配置文件中check_http名对应的命令
          check_interval			10				# 正常情况下,每隔10分钟检查一次
          check_period			24*7			# 什么时间段允许检查
          retry_interval			1				# 上一次检查出现问题,重试每隔1分钟检查一次
      	max_check_attempts		3				# 重试3次后,改为硬状态,发告警
      	notification_interval	30				# 问题不解决的情况下,每隔30分钟发一次告警
      	notification_period		24*7			# 什么时间段允许发告警
      	notification_options	w,c,u,r			# 什么状态下发告警
      		# w:warning			警告
      		# c:CRITICAL 		危急,出故障了
      		# u:UNREACHABLE		不可达
      		# r:Recovery(OK)	恢复了
      		# f:notify when the service starts and stops flapping	一会儿好一会儿坏
      		# s:scheduled downtime starts or ends	计划停机时间开始或结束,比如计划今天凌晨1点到3点对系统进行维护
      	contact_groups			web_admin		# 出现故障联系人
      }
      
    • 排除检查主机(!)

      # 对linux-servers主机组中除了srv01和srv02两台主机外其他的所有主机进行监控
      define service{
      	hostgroup_name		linux-servers
      	host_name			!srv01,srv02
      	service_description	SSH
      	...
      }
      
  • Service group

    #第一种定义方式,创建组然后向组中加入主机和对应的服务
    # Service Group 成员是多个 <host>,<service>对
    define servicegroup{
        servicegroup_name	databaseservices
        alias				All services related to databases
        members				srv01,mysql,srv101,pgsql,aix01,db2
        # 表示srv01主机的mysql服务,srv01主机的pgsql服务,aix01的db2服务
    }
    
    # 第二种定义方式,创建服务,然后在服务中配置此服务属于哪个组
    define servicegroup{	# 先定义服务组
    	servicegroup_name	databaseservices
    	alias				All services related to database
    }
    define service{			# 定义服务
    	host_name			linuxbox01
    	service_description	mysql
    	check_command		check_ssh
    	servicegroups		databaseservices	# 定义此服务属于databaseservices组
    }
    
  • 配置图示

  • Command

    • 简介

      • 如何检查 Host / Service(H/S 使用 Command)
      • 如何问题告警 / 事务处理
      • 两个参数:名称、命令行
      • 命令执行插件或自定义命令
      • 命令行会使用宏、参数等(ARG1 , ARG2 ... ARG32),最多使用32个参数
    • 配置

      # 不使用参数的例子
      # 定义command
      define command{
          command_name 	check-host-alive
          command_line 	$USER1$/check_ping -H $HOSTADDRESS$ -w 3000.0,80% -c 5000.0,100% -p 5	# 执行$USER1$对应的插件目录下check_ping命令,-H参数指定目标主机,-w参数指定丢包达到80%就将主机状态改为warning状态,-c参数指定丢包达到100%就将主机状态设置为critical状态
      }
      # 定义host,在其中使用上面定义的command
      define host{
          host_name		somemachine
          address			10.0.0.1
          check_command 	check-host-alive	# 执行command配置中check-host-alive名字对应的命令
      }
      
      # 使用参数的例子
      define command{
      	command_name 	check-host-alive
      	command_line 	$USER1$/check_ping -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$ -p 5
      	# -w参数指定什么时候将主机状态设置为warning,这里用 $ARG1$ 代替,由host定义时传递
      	# -c参数指定什么时候将主机状态设置为critical,这里用 $ARG2$ 替代,由host定义时传递
      	# 这样不同的主机传递不同的参数,就设置了不同的warning和critical条件
      }
      # 定义host,在其中使用上面带参数定义的command,并传递参数
      define host{
      	host_name		somemachine
      	address			10.0.0.1
      	check_command 	check-host-alive!3000.0,80%!5000.0,100%
      	# 执行command配置中check-host-alive名字对应的命令,并传递命令所需要的两个参数,用!分割参数
      }
      
  • Time periods

    • 简介

      • 执行检查、告警的时间区段
    • 配置

      # 定义工作日的工作时间
      define timeperiod{
          timeperiod_name		workinghours	# 取一个名字
          alias				Working Hours, from Monday to Friday	# 别名
          monday				09:00-17:00		# 星期一 09:00-17:00 才进行监控
          tuesday				09:00-17:00		# 星期二 09:00-17:00 才进行监控
          wednesday			09:00-17:00		# 星期三 09:00-17:00 才进行监控
          thursday			09:00-17:00		# 星期四 09:00-17:00 才进行监控
          friday				09:00-17:00		# 星期五 09:00-17:00 才进行监控
          exclude				first-mondays	# 排除每个月的第一个星期一不进行监控
      }
      
      # 日期格式优先级(按时间颗粒度排序)------优先级从高到底
      #		YYYY-MM-DD		具体日期,某年某月某日,例如:2018-11-11(优先级最高)
      #		July 4			每年指定日期
      #		day 14			每月指定日期
      #		Monday 1 April	具体月指定星期(例如:4月第一个星期一)
      #		Monday 1		每月指定星期(例如:每个月第一个星期一)
      #		Monday			每星期一
      
      # 定义休息天整天
      define timeperiod{
          timeperiod_name		weekends
          alias				Weekends all day long
          saturday			00:00-24:00
          sunday				00:00-24:00
      }
      
      # Nagios定义好了的 7x24小时
      define timeperiod {
          name                    24x7
          timeperiod_name         24x7
          alias                   24 Hours A Day, 7 Days A Week
          sunday                  00:00-24:00
          monday                  00:00-24:00
          tuesday                 00:00-24:00
          wednesday               00:00-24:00
          thursday                00:00-24:00
          friday                  00:00-24:00
          saturday                00:00-24:00
      }
      
  • Contacts

    # 定义联系人
    define contact{
        contact_name					zs						# 名称,不可重复
        alias							zhang san				# 别名
        email							zs@lab.com				# 邮箱地址
        contactgroups					admins,nagiosadmin		# 加入到联系人组中
        host_notification_period		workinghours			# host故障时,什么时间可以给此联系人发告警,前提是在Time periods配置文件中配置好了 workinghours 对应的时间配置
        service_notification_period		workinghours			# service故障时,什么时间可以给此联系人发告警,前提是在Time periods配置文件中配置好了 workinghours 对应的时间配置
        host_notification_options		d,u,r					# host是什么状态时发告警
        service_notification_options	w,u,c,r					# service是什么状态时发告警
        host_notification_commands		notify-host-by-email	# host故障时,用什么命令给此联系人发告警,前提是在command配置文件中配置好了 notify-host-by-email 对应的命令
        service_notification_commands	notify-service-by-email	# service故障时,用什么命令给此联系人发告警,前提是在command配置文件中配置好了 notify-service-by-email 对应的命令
    }
    # host_notification_options(host告警选项)
    #		d : DOWN
    #       u : UNREACHABLE
    #       r : Recovery (UP)
    #       f : starts / stops Flapping
    #       s : Scheduled downtime starts / ends
    #       n : Not receive any notifications		# 不接收任何host告警
    
    # service_notification_options(service告警选项)
    #		w : WARNING
    #		u : UNKNOWN
    #		c : CRITICAL
    #		r : Recovery (OK)
    #		f : the service starts and stops flapping
    #		n : the person will not receive any service notifications	# 此联系人不接收任何service告警
    
  • Contact Group

    • 简介

      • 指定时间联系指定人群
      • 硬件问题联系硬件管理员,服务问题联系系统管理员
    • 配置

      define contactgroup{
          contactgroup_name		linux-admins			# 此联系人组名称,不可重复
          alias					Linux Administrators	# 别名
          members					jdoe,smith				# 此组中包含的联系人
          contactgroup_members	testGroup				# 把别的组加入到此组中
      }
      
  • 验证配置文件并重启服务

    • 重启服务/系统前验证配置,避免监控服务宕机
    1. 检查主配置文件即可,因为主配置文件中包含了其他所有的配置文件内容 ,命令:sudo /opt/nagios/bin/nagios -v /etc/nagios/nagios.cfg
    2. 配置文件没有问题后,重启服务使配置生效 ,命令:sudo systemctl restart nagios.service
  • 继承和模板

    • 简介

      • 定义新对象时可重用模板定义的参数,简化管理
      • 不加 register 的模板对象将被视为普通对象进行监控
      • 通过 use 指令调用模板定义对象
      • 定义对象时可使用多个模板,按模板先后顺序确定优先级
      • 模板可层级继承调用,定义新的模板
    • 定义模板

      # 定义一个host模板,模板也可以使用模板,使用use使用
      define host{
          name					generic-server
          check_command 			check-host-alive
          check_interval			5
          retry_interval			1
          max_check_attempts		5
          check_period			24x7
          notification_interval	30
          notification_period 	24x7
          notification_options	d,u,r
          register				0		# 表示这是一个模板,必须要加,否则就当做一个host配置了
      }
      
      # 定义host并使用模板
      define host{
          use						generic-server		# 使用 generic-server 模板
          host_name				linuxbox01
          alias					Linux Server 01
          address					10.0.2.1
          contact_groups			linux-admins
      }
      

15.2.5 Web界面 {#1525-web界面}

  • 查看性能、故障、状态、历史信息

  • 支持修改部分设置

  • 状态、报告、系统

  • Nagios Exchange(社区站点)
    -- 包含不同类型的插件和扩展
    -- http://exchange.nagios.org/directory/Addons/Frontends-(GUIs-and-CLIs)/Web-Interfaces 下载插件,然后将下载的php文件放到Nagios网站目录中去,再使用浏览器访问

  • 修改Nagios的Web主页面为service监控信息,这样登录上去就能看见监控的信息了(默认的主页没什么有用的监控信息)

    • 修改站点php文件,命令:sudo vim /opt/nagios/share/index.php

      # 第三行
      $url = 'main.php';	//将这一行修改为 $url="cgi-bin/status.cgi?host=all&limit=0";
      

15.2.6 安装Nagiosgraph {#1526-安装nagiosgraph}

  • 简介

    • 基于RRDtool实现历史数据的图形化显示(曲线图表)
    • 由 perl 语言编写
  • 安装步骤

    1. 安装依赖包 ,命令:sudo apt -y install libcgi-pm-perl librrds-perl libgd-gd2-perl rrdtool perl libgd-perl

    2. 下载源码并安装

      1. 下载源码并解包 ,命令:curl -sSL https://sourceforge.net/projects/nagiosgraph/files/latest/download | tar xzv

      2. 进入解压得到的目录 ,命令:cd nagiosgraph-1.5.2

      3. 安装 ,命令:sudo perl install.pl

        Destination directory (prefix)? [/usr/local/nagiosgraph]	# 安装到哪  
        Location of configuration files (etc-dir)? [/usr/local/nagiosgraph/etc]	# 配置文件放到哪
        Location of executables? [/usr/local/nagiosgraph/bin] 
        Location of CGI scripts? [/usr/local/nagiosgraph/cgi] 
        Location of documentation (doc-dir)? [/usr/local/nagiosgraph/doc] 
        Location of examples? [/usr/local/nagiosgraph/examples] 
        Location of CSS and JavaScript files? [/usr/local/nagiosgraph/share] 
        Location of utilities? [/usr/local/nagiosgraph/util] 
        Location of state files (var-dir)? [/usr/local/nagiosgraph/var] 
        Location of RRD files? [/usr/local/nagiosgraph/var/rrd] 
        Location of log files (log-dir)? [/usr/local/nagiosgraph/var/log] 
        Path of log file? [/usr/local/nagiosgraph/var/log/nagiosgraph.log] 
        Path of CGI log file? [/usr/local/nagiosgraph/var/log/nagiosgraph-cgi.log] 
        Base URL? [/nagiosgraph]	# 访问的URL
        URL of CGI scripts? [/nagiosgraph/cgi-bin] 
        URL of CSS file? [/nagiosgraph/nagiosgraph.css] 
        URL of JavaScript file? [/nagiosgraph/nagiosgraph.js] 
        URL of Nagios CGI scripts? [/nagios/cgi-bin] 
        Path of Nagios performance data file? [/tmp/perfdata.log] 
        username or userid of Nagios user? [nagios]	# 运行Nagios服务的账号
        username or userid of web server user? [www-data]	# 运行web服务的账号
        Modify the Nagios configuration? [n] y	# 选y,允许修改Nagios配置文件,这样才能从Nagios那里获取数据
        Path of Nagios configuration file? [/etc/nagios/nagios.cfg]	# Nagios主配置文件位置
        Path of Nagios commands file? [/etc/nagios/objects/commands.cfg]	# command配置文件位置,如果自己修改了位置要配置正确的位置
        Modify the Apache configuration? [n] y	# 选y,允许修改Apache的配置文件,因为nagiosgraph要创建一个新的站点
        Path of Apache configuration directory? /etc/apache2/sites-available	# nagiosgraph站点配置文件放到哪里,也可以写/etc/apache2/sites-enabled这样直接就启用了站点,不用再用a2ensite nagiosgraph.conf来启用站点了
        configuration:
          ng_prefix            /usr/local/nagiosgraph
          ng_etc_dir           /usr/local/nagiosgraph/etc
          ng_bin_dir           /usr/local/nagiosgraph/bin
          ng_cgi_dir           /usr/local/nagiosgraph/cgi
          ng_doc_dir           /usr/local/nagiosgraph/doc
          ng_examples_dir      /usr/local/nagiosgraph/examples
          ng_www_dir           /usr/local/nagiosgraph/share
          ng_util_dir          /usr/local/nagiosgraph/util
          ng_var_dir           /usr/local/nagiosgraph/var
          ng_rrd_dir           /usr/local/nagiosgraph/var/rrd
          ng_log_dir           /usr/local/nagiosgraph/var/log
          ng_log_file          /usr/local/nagiosgraph/var/log/nagiosgraph.log
          ng_cgilog_file       /usr/local/nagiosgraph/var/log/nagiosgraph-cgi.log
          ng_url               /nagiosgraph
          ng_cgi_url           /nagiosgraph/cgi-bin
          ng_css_url           /nagiosgraph/nagiosgraph.css
          ng_js_url            /nagiosgraph/nagiosgraph.js
          nagios_cgi_url       /nagios/cgi-bin
          nagios_perfdata_file /tmp/perfdata.log
          nagios_user          nagios
          www_user             www-data
          modify_nagios_config y
          nagios_config_file   /etc/nagios/nagios.cfg
          nagios_commands_file /etc/nagios/objects/commands.cfg
          modify_apache_config y
          apache_config_dir    /etc/apache2/sites-available
          apache_config_file   
        Continue with this configuration? [y]	# 上面填写的没有问题之后,确定安装
        
    3. 配置

      1. 修改nagiosgraph自动创建的Apache站点配置文件,因为默认创建的有点问题,命令:sudo vim /etc/apache2/sites-available/nagiosgraph.conf

        # enable nagiosgraph CGI scripts
        ScriptAlias /nagiosgraph/cgi-bin "/usr/local/nagiosgraph/cgi"
        <Directory "/usr/local/nagiosgraph/cgi">
           Options ExecCGI
           AllowOverride None
           Order allow,deny		# 删掉这一行
           Allow from all		# 将这一行改为 Require all granted
        #   AuthName "Nagios Access"
        #   AuthType Basic
        #   AuthUserFile NAGIOS_ETC_DIR/htpasswd.users
        #   Require valid-user
        </Directory>
        # enable nagiosgraph CSS and JavaScript
        Alias /nagiosgraph "/usr/local/nagiosgraph/share"
        <Directory "/usr/local/nagiosgraph/share">
           Options None
           AllowOverride None
           Order allow,deny		# 删掉这一行
           Allow from all		# 将这一行改为 Require all granted
        </Directory>
        

      2. 启用站点,命令:sudo a2ensite nagiosgraph.conf

      3. 重启服务,使配置生效

        • 重启Apache服务,命令:sudo systemctl restart apache2.service
        • 重启Nagios服务,命令:sudo systemctl restart nagios.service
    4. 使用浏览器访问,http://ip/nagiosgraph/cgi-bin/show.cgi

  • 将nagiosgraph加入到Nagios主站中

    # 想要显示图表的service中添加下面这段配置
    # 最好配置在service的模板中,然后让service中使用此模板,这样所有的在ngios的web界面中所有的service都会显示图表了
    action_url /nagiosgraph/cgi-bin/show.cgi host=$HOSTNAME$&service=$SERVICEDESC$&geom=1000x2
    00	
    # 将/nagiosgraph/cgi-bin/show.cgi这个路径下host=$HOSTNAME,service=$SERVICEDESC这个图表以1000x200的大小包含进来(大小可以不配置),这样在nagios的web页面上直接就能显示nagiosgraph中的图表信息了,而不需要特地访问nagiosgraph的web页面
    
    • 重启服务,使配置生效
      • 重启Apache服务,命令:sudo systemctl restart apache2.service
      • 重启Nagios服务,命令:sudo systemctl restart nagios.service
    • 访问Nagios的web界面即可

15.2.7 集成 mrtg + nagiosgraph {#1527-集成-mrtg--nagiosgraph}

  • 简介

    • MRTG监视nagios的运行状态
  • 安装步骤

    1. 安装,命令:sudo apt install mrtg

    2. 创建mrtg收集数据的存放目录 ,命令:sudo mkdir /opt/nagios/share/stats

    3. 配置mrtg

      • 在下载Nagios的源码文件中就已经包含了一个关于mrtg的配置文件了,所以只需要将Nagios源码包中的mrtg配置文件复制到Nagios的配置目录中然后在Nagios主配置文件中配置即可
      1. 复制mrtg配置文件到Nagios配置目录中 ,命令:sudo cp ~/nagios-4.4.2/sample-config/mrtg.cfg /etc/nagios

      2. 编辑mrtg配置文件 ,命令:sudo vim /etc/nagios/mrtg.cfg

        # 在mrtg.cfg配置文件中新增这一行
        WorkDir: /opt/nagios/share/stats	# 指定工作目录
        
      3. 测试是否可以运行起来 ,命令:sudo env LANG=C mrtg /etc/nagios/mrtg.cfg 有warning不要紧

      4. 创建主页文件 ,命令:sudo indexmaker /etc/nagios/mrtg.cfg --output=/opt/nagios/share/stats/index.html

      5. 让mrtg周期性的收集数据 ,命令:sudo vi /etc/cron.d/nagiostats 内容如下

        */5 * * * * root env LANG=C /usr/bin/mrtg /etc/nagios/mrtg.cfg	# 每5分钟以root账号运行后面的命令
        
    4. 使用浏览访问,http://ip/nagios/stats/

  • 将mrtg 和 nagiosgraph放到Nagios主页中的左侧导航栏中

    • 编辑站点PHP文件,命令:udo vim /opt/nagios/share/side.php 添加的位置添加下面内容

      <div class="navsection">
          <div class="navsectiontitle">External Tools</div>
          <div class="navsectionlinks">
          <ul class="navsectionlinks">
              <li><a href="/nagios/stats" target="<?php echo $link_target;?>">Nagiostats</a></li>
              <li><a href="/nagiosgraph/cgi-bin/show.cgi" target="<?php echo $link_target;?>">Nagiosgraph</a></li>
          </ul>
          </div>
      </div>
      

15.2.8 通过SSH实现远程监控 {#1528-通过ssh实现远程监控}

  • SSH 远程监控

    • 监视远程主机的CPU、内存、存储等
    • 利用SSH在远程主机上执行插件并返回结果及退出代码
    • SSH 基于密钥的身份认证
    • check_by_ssh 插件建立SSH连接,指定主机名和具体执行的命令

  • 步骤

    1. Nagios client安装配置

      1. 安装依赖 ,命令:sudo apt -y install gcc make binutils cpp

      2. 下载插件源码 ,命令:wget https://nagios-plugins.org/download/nagios-plugins-2.2.1.tar.gz

      3. 解包源码 ,命令:tar zxvf nagios-plugins-2.2.1.tar.gz

      4. 进入解包得到的源码目录 ,命令:cd nagios-plugins-2.2.1/

      5. 配置 ,命令:sudo sh configure --prefix=/opt/nagios --sysconfdir=/etc/nagios --localstatedir=/var/nagios --libexecdir=/opt/nagios/plugins

        • --prefix=/opt/nagios 指定程序(二进制)将来安装的位置
        • --sysconfdir=/etc/nagios 指定配置文件存放位置
        • --localstatedir=/var/nagios 指定历史状态数据存放位置
        • --libexecdir=/opt/nagios/plugins 指定插件存放位置
      6. 编译 ,命令:sudo make all

      7. 安装 ,命令:sudo make install

      8. ssh配置

        1. 配置ssh可以通过秘钥身份认证 ,命令:sudo vim /etc/ssh/sshd_config

          PubkeyAuthentication yes	# 取消此行注释
          
        2. 重启ssh服务,使配置生效 ,命令:sudo systemctl restart ssh.service

      9. 生成供Nagios服务通过ssh远程连接的账号

        1. 创建账号 ,命令:sudo useradd -d /opt/nagios/ nagios
        2. 更改主目录的属主和属组为nagios ,命令:sudo chown nagios:nagios /opt/nagios/
        3. 设置nagios账号的密码 ,命令:sudo passwd nagios
    2. 在nagios服务上生成秘钥对

      1. 将自己切换为nagios账号,因为将来使用nagios账号用ssh连接远程被监视的主机

        1. 先将自己切换为root账号 ,命令:sudo -i
        2. 然后再将自己切换为nagios账号 ,命令:su -s /bin/bash nagios
      2. 生成秘钥对 ,命令:ssh-keygen

      3. 将公钥拷贝到被监视的服务器上去 ,命令:ssh-copy-id nagios@192.168.2.231

    3. 在nagios服务器端配置

      1. 检测nagios服务是否可以通过ssh连接被检测主机并执行监控命令 ,命令:/opt/nagios/plugins/check_by_ssh -H 192.168.20.12 -C "/opt/nagios/plugins/check_uptime" 检测主机的开机时间

      2. 定义nagios配置

        # 定义检测命令
        define command{
            command_name	check_swap_by_ssh
            command_line	$USER1$/check_by_ssh -H $HOSTADDRESS$ -C "$USER1$/check_swap -w $ARG1$ -c $ARG2$"
        }
        
        define service{
            use						generic-service
            host_name				!localhost			# 排除本机
            hostgroup_name			linux-servers
            service_description		SWAP
            check_command			check_swap_by_ssh!15%!90%	# 检查命令,传递参数
        }
        

15.2.9 通过NRPE实现远程监控 {#1529-通过nrpe实现远程监控}

  • 简介

    • 客户端/服务器架构(check_nrpe 插件、NRPE daemon)
    • 通信支持加密(SSL over TCP)
    • 通信流量小于 SSH、节省CPU
    • 只允许运行特定命令,不会造成任意指令执行(SSH会)。
    • 默认工作端口 TCP 5666

  • 安装步骤

    1. 被监视主机上

      1. 安装依赖包 ,命令:sudo apt install gcc make binutils cpp pkg-config libc6-dev libssl-dev openssl

      2. 安装NRPE服务

        • 方式一,通过APT安装 ,命令:sudo apt install nagios-nrpe-server(这里使用这种方式)

        • 方式二,手动编译安装

          1. 下载源码包 ,命令:wget https://sourceforge.net/projects/nagios/files/nrpe-2.x/nrpe-2.15/nrpe-2.15.tar.gz

          2. 解包源码包 ,命令:tar zxvf nrpe-2.15.tar.gz

          3. 进入到得到的源码目录中 ,命令:cd nrpe-2.15

          4. 配置

            # 命令行执行下面的命令
            sh configure \
            --sysconfdir=/etc/nagios \			# 配置文件存放目录
            --libexecdir=/opt/nagios/plugins \	# 二进制,可执行程序存放目录
            --prefix=/opt/nagios \				# 指定安装目录
            --localstatedir=/var/nagios \		# 状态文件存放目录
            --with-nrpe-user=nagios \			# 运行时用的用户账号
            --with-nrpe-group=nagios \			# 运行时用的组账号
            --with-nagios-user=nagios \
            --with-nagios-group=nagios \
            --with-ssl-lib=/usr/lib/x86_64-linux-gnu \
            --enable-ssl						# 启用ssl
            
          5. 编译 ,命令:make all

          6. 安装 ,命令:sudo make install-daemon

          7. 创建配置文件存放目录 ,命令:sudo mkdir /etc/nagios

          8. 安装配置文件 ,命令:sudo make install-daemon-config

          9. 创建运行账号

            1. 创建运行nrpe的账号 ,命令:sudo useradd -d /opt/nagios nagios
          10. 创建nagios账号主目录 ,命令:sudo mkdir /opt/nagios

            1. 更改nagios目录的属主与属组 ,命令:sudo chown nagios:nagios /opt/nagios
          11. 设置nagios账号的密码 ,命令:sudo passwd -l nagios

        1. 配置自动启动脚本

          1. 创建并编辑启动脚本 ,命令:sudo vim /etc/init.d/nrpe

            ```sh
            #!/bin/sh
            is_running() {
                pgrep -u nagios nrpe >/dev/null
            }
            case "$1" in
                start)
                    echo -n "Starting NRPE: "
                    if ! is_running ; then
                        /opt/nagios/bin/nrpe -d -c /etc/nagios/nrpe.cfg
                    fi
                    echo "done."
                    ;;
            stop)
                    echo -n "Stopping NRPE: "
                if is_running ; then
                        pkill -u nagios nrpe
                        sleep 1
                        pkill -u nagios -9 nrpe
                    fi
                    echo "done."
                    ;;
                restart)
                    $0 stop
                    sleep 2
                    $0 start
                    ;;
                status)
                    if is_running ; then
                        echo "NRPE is running"
                        exit 0
                    else
                        echo "NRPE is NOT running"
                        exit 1
                    fi
                    ;;
            esac
            ```
            
            1. 设置启动脚本文件权限 ,命令:sudo chmod 0755 /etc/init.d/nrpe

            2. 更新 ,命令:sudo update-rc.d nrpe

              • 这样就可以使用systemctl命令来启动,重启,关闭nrpe服务了
      3. 配置nrpe

        1. 编辑nrpe配置文件 ,命令:sudo vim /etc/nagios/nrpe.cfg

          allowed_hosts=192.168.2.247,::1		# 默认情况下只允许本机连接nrpe运行端口,需要将Nagios服务器的ip写到这里,运行Nagios服务器连接被监视机器的nrpe 5666端口
          
          # 你可以在此配置文件中加自己的要监视的具体命令,它默认的有如下几个
          command[check_users]=/usr/lib/nagios/plugins/check_users -w 5 -c 10
          # check_users 是这条命令的名称,Nagios服务器传递过来这条名称,nrpe就会执行这个名称所对应的命令
          command[check_load]=/usr/lib/nagios/plugins/check_load -r -w .15,.10,.05 -c .30,.25,.20
          command[check_hda1]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p /dev/hda1
          command[check_zombie_procs]=/usr/lib/nagios/plugins/check_procs -w 5 -c 10 -s Z
          command[check_total_procs]=/usr/lib/nagios/plugins/check_procs -w 150 -c 200
          
        2. 重启nrpe服务,使配置生效 ,命令:sudo systemctl restart nagios-nrpe-server.service

    2. Nagios服务器上(监视端)

      1. 安装nrpe扩展

        • 方式一,通过APT安装 ,命令:sudo apt install nagios-nrpe-plugin(这里使用这种方式)

        • 方式二,手动编译安装

          1. 下载源码包 ,命令:wget https://sourceforge.net/projects/nagios/files/nrpe-2.x/nrpe-2.15/nrpe-2.15.tar.gz

          2. 解包源码包 ,命令:tar zxvf nrpe-2.15.tar.gz

          3. 进入到得到的源码目录中 ,命令:cd nrpe-2.15

          4. 配置

            # 命令行执行下面的命令
            sh configure \
            --sysconfdir=/etc/nagios \			# 配置文件存放目录
            --libexecdir=/opt/nagios/plugins \	# 二进制,可执行程序存放目录
            --prefix=/opt/nagios \				# 指定安装目录
            --localstatedir=/var/nagios \		# 状态文件存放目录
            --with-nrpe-user=nagios \			# 运行时用的用户账号
            --with-nrpe-group=nagios \			# 运行时用的组账号
            --with-nagios-user=nagios \
            --with-nagios-group=nagios \
            --with-ssl-lib=/usr/lib/x86_64-linux-gnu \
            --enable-ssl						# 启用ssl
            
          5. 编译 ,命令:make all

          6. 安装 ,命令:sudo make install-plugin

      2. 测试是否能连通被监视端nrpe服务,并得到检查结果

        • APT安装方式执行此命令,因为APT安装方式默认会将nrpe放到/usr/lib/nagios目录下 ,命令:/usr/lib/nagios/plugins/check_nrpe -H 192.168.2.52 -c check_users check_user就是被监视机器上nrpe配置文件中配置的服务名称,将check_user这个名称传过去,被监视端的nrpe就会执行check_user对应的命令并返回检查结果,前提是在被监视端已经配置好check_user这个命令
        • 手动编译安装执行此命令(你安装到哪就从哪执行check_nrpe这个插件的命令) ,命令:/opt/nagios/plugins/check_nrpe -H 192.168.2.52 -c check_users 查看被监视机器上有几个被登录账号
      3. 配置Nagios使用NRPE

        # 在Nagios配置文件中定义一个命令,然后再把此命令加入到相关的service和host中即可
        define command
        {
            command_name	check_swap_nrpe	
            command_line	$USER1$/check_nrpe -H "$HOSTADDRESS$" -c "check_users"	
            # check_users:被监视主机上NRPE中配置的命令名称
        }
        

15.2.10 通过SNAP实现远程监控 {#15210-通过snap实现远程监控}

  • SNMP(Simple Network Management Protocol)

    • 工业标准,(原则上)所有设备厂商都支持
    • 适合非通用操作系统的硬件设备(无法安装插件、nrpe)
    • 统一的方法获取和设置设备参数
    • 标准的层次化信息分组访问方式,称为管理信息库
    • Management Information Base(MIB)
    • MIB定义可访问的属性,即标准OID的对应关系
    • 厂商可自定义OID(不兼容)
    • OID(Object identifier)
    • 协议端口:UDP 161(Agent) / 162(Manager)

  • 概述

    • 被监视端运行 agent 进程侦听端口,监视端称为 SNMP manager
    • get / set 是从 manager 向 agent 的通信过程
    • trap 是 agent 主动向 manager 通告信息的通信过程
    • 版本:v1、v2、v2c、v2u、v3
      • v1 基于 IP / community(public/private)的安全机制
      • v2、v2c 增加了 getbulk(获取节点下所有数据)、inform(trap------请求manager确认ACK)
      • v2u 基于用户的身份验证安全机制(但不包含v1、v2c其他安全机制,很少用)
    • v3改进了安全模型,认证、隐私、访问控制
    • 检查设备支持SNMP什么版本(proxy用于多版本之间的协调转换)
  • 仅使用SNMP进行监控

    1. 监控机上,安装Manage部分,安装 Net-SNMP 工具包、MIB 文件库(manager)

      1. 安装Manage相关软件包 ,命令:sudo apt install snmp snmp-mibs-downloader
      2. 安装完上面的软件包之后,就会有很多snmp开头的命令,例如snmpget、snmpwalk等
    2. 被监控机上,安装 SNMP Agent

      1. 安装软件包 ,命令:sudo apt install snmpd

      2. 编辑配置文件 ,命令:sudo vim /etc/snmp/snmpd.conf

        agentAddress  udp:192.168.2.231:161		# 修改侦听ip,可以改为0.0.0.0或某一个网卡的ip
        
        # 修改community,如果使用默认的public,那么大家都可以使用public来查询你这个机器信息,例如这里改为pub1
        rocommunity pub1  default    -V systemonly		# ipv4
        rocommunity6 pub1  default   -V systemonly		# ipv6
        
      3. 重启服务,使配置生效 ,命令:sudo systemctl restart snmpd.service

    3. 测试

      • 命令:snmpget -v 2c -c pub1 192.168.2.231 .1.3.6.1.2.1.1.5.0 通过snmp获取一个设备上的一个查询结果

        • -v:指定使用的SNMP协议的版本
        • -c:自定community
        • 192.168.2.231:要查询的目标ip
        • .1.3.6.1.2.1.1.5.0:查询计算机名的OID
      • 命令:snmpwalk -v 1 -c pub1 192.168.2.231 .1.3.6.1.2.1.1 通过snmpwalk使用指定OID开头的所有的OID来进行查询

        • .1.3.6.1.2.1.1:会以.1.3.6.1.2.1.1开头,然后挨个使用下面所有的OID进行查询

  • nagios 基于 snmp 监控

    1. 首先先要在目标机器上配置好了SNMP
    • 手动执行查询命令,使用Nagios的check_nagios插件 或 check_ifoperstatus

      • 命令:/opt/nagios/plugins/check_snmp -H 192.168.2.231 -P 2c -C pub1 -o SNMPv2 MIB::sysLocation.0 -s "lw"
        • -c:指定要查询的主机
        • -P:使用SNMP哪个版本
        • -C:指定community
        • -o:指定查询OID
        • SNMPv2 MIB::sysLocation.0:查询的OID,这里是查询主机放置的位置
        • -s:精确搜索,大小写区分,这里是显示结果是lw的
          • -r:模糊搜索
      • 命令:/opt/nagios/plugins/check_snmp -H 10.0.0.1 -P 2c -C public -o SNMPv2-
        MIB::sysContact.0 -r "@" 查联系人信息
      • 命令:/opt/nagios/plugins/check_snmp -H 10.0.0.1 -P 2c -C public -o HOST-
        RESOURCES-MIB::hrSystemProcesses.0 -w 0:20 -c 0:30 查系统进程树,大于20就warning,大于30就critical
      • 命令:/opt/nagios/plugins/check_ifoperstatus -H 10.0.0.1 -C pub1 -k 65539 查网卡状态
        • -k:指定网卡索引,每个网卡在系统中都有一个索引ID
      • 命令:**/opt/nagios/plugins/check_ifstatus -H 10.0.0.1 -v 2c -C public1 -u 65539 ** 查网卡状态
    • 结合Nagios和SNMP

      # 定义command然后在service中使用
      define command{
          command_name		check_snmp
          command_line		$USER1$/check_snmp -P 1 -H $HOSTADDRESS$ -o $ARG1$ $ARG2$
      }
      define service
      {
          use					generic-service
          hostgroup_name		snmp-aware
          service_description	Processes
          check_command		check_snmp!HOST-RESOURCES-MIB::hrSystemProcesses.0!-w 0:50 -c 0:100
      }
      
      # 定义command然后在host中定义自定义宏
      define command{
          command_name 		check_snmp
          command_line 		$USER1$/check_snmp -H $HOSTADDRESS$ -o $ARG1$ -P $_HOSTSNMPVERSION$ -C $_HOSTSNMPCOMMUNITY$ $ARG2$
      }
      define host{
          use					generic-host
          host_name			linuxbox01
          address				10.0.0.1
          _SNMPVERSION		2c
          _SNMPCOMMUNITY		public
      }
      

第 16 章 版本控制 {#第-16-章-版本控制}

16.1 版本控制简介 {#161-版本控制简介}

16.1.1 简介 {#1611-简介}

  • version control system
  • revision control system(修订控制系统)
  • 开发工具,但不仅限于源码文件
  • 记录文件的每次变更
  • 随时可以回到历史状态
  • 文件及元数据的变更(修改人、修改理由、具体修改内容、时间戳)
  • 配置文件是除数据之外第二大资产
  • 团队协作

16.1.2 软件分类 {#1612-软件分类}

  • centralized version control systems(CVCS)
    • 集中存储修改,所有的文件存放到一个位置,版本颗粒小,可以进行精确的修改恢复,但是单点故障隐患
    • CVS / Subversion
  • distributed version control systems(DVCS)
    • 分布式存储库的完整拷贝
    • Git / Mercurial / Bazaar
    • 每个人维护本地库,完成后上传到服务器
  • 指针指向当前最新版本
  • 随时回滚还原历史版本

16.2 Git {#162-git}

16.2.1 简介 {#1621-简介}

  • 最初由李纳斯开发(Linux 内核创始者)
  • Git 作为开发工具而生
  • 适合大型项目的版本管理(源码版本管理)
  • Git 库保存所有程序员的团队成果
  • Git 默认使用OpenSSH
  • 服务器上Git用户需要能够修改目录(库)
  • 一个库就是一个文件夹(库配置信息 .git目录)
  • 无需独立的专职服务期,满足存储空间需求可共用
  • github 目前世界上最大的代码托管服务商(已被微软收购)

16.2.2 服务端安装和使用 {#1622-服务端安装和使用}

  • Git的服务器端软件包和客户端软件包是同一个软件包

  • 安装

    • 系统库安装方式 ,命令:sudo apt install git
    • PPA库安装方式
      1. 添加git官方PPA库 ,命令:sudo add-apt-repository ppa:git-core/ppa
      2. 更新索引 ,命令:sudo apt update
      3. 安装git ,命令:sudo apt install git
      4. 查看git版本 ,命令:git version PPA库中git版本新于Ubuntu官方库
  1. 使用:创建Git库
    1. 创建目录 ,命令:sudo mkdir /git 总库目录,这个目录下存放其他所以的库
    2. 将目录属主和属组改为日常服务器管理员账号和组 ,命令:sudo chown lw:lw /git
    3. 进入总库目录中 ,命令:cd /git
    4. 给某个特定的项目或什么创建库,例如这里给Apache创建一个库 ,命令:git init --bare apache2 创建出来的apache2库是空的框架库,不存在数据
  • 故障诊断

    • 因为客户端连接git库是通过ssh连接的,当连接不上时可以查看服务器端的ssh日志来进行问题的判断
    • /var/log/auth.log SSH 登陆问题诊断

16.2.3 客户端安装和使用 {#1623-客户端安装和使用}

  • Git的服务器端软件包和客户端软件包是同一个软件包

  • 安装

    • 系统库安装方式 ,命令:sudo apt install git
    • PPA库安装方式
      1. 添加git官方PPA库 ,命令:sudo add-apt-repository ppa:git-core/ppa
      2. 更新索引 ,命令:sudo apt update
      3. 安装git ,命令:sudo apt install git
      4. 查看git版本 ,命令:git version PPA库中git版本新于Ubuntu官方库
  • 客户端使用方法

    • 第一次使用之前,需要配置使用这个git的用户名和邮箱,这样使用git提交时服务器就会记录这次提交的是谁和联系方式等方便以后查看

      • 以下两条命令只用执行一次,执行后会写入到本地库中,如果提交的话也会存储到服务器库存储中
      • 配置用户名 ,命令:git config --global user.name "luo"
      • 配置邮箱 ,命令:git config --global user.email "luo@xxx.com"
      • 查看已配置的信息 ,命令:git config --list
    • 查看帮助信息

      • 查看常用二级命令 ,命令:git help

      • 查看全部二级命令 ,命令:git help -a

      • 查看概念帮助 ,命令:git help -g

      • 查看具体某个二级命令或概念怎么使用 ,命令:git help <二级命令>或git help <概念>

    • 作为客户端连接服务器的Git库

      • 因为git服务端和客户端软件包是一样的,所以本地的git也可以用作本地的Git库而不用去连接服务器的Git库
      1. 连接服务器Git库之前,先要配置好存放所有Git库的目录

        1. 创建目录 ,命令:sudo mkdir /git 总库目录,这个目录下存放其他所以的库
        2. 将目录属主和属组改为日常服务器管理员账号和组 ,命令:sudo chown lw:lw /git
      2. 克隆库

        1. 进入总库目录中 ,命令:cd /git

        2. 复制服务器Git库到本地 ,命令:git clone lw@192.168.2.231:/git/web 克隆之后,会在本地生成web库,在web库中有一个.git的隐藏目录,里面存放了各种配置信息,包括连接服务器库的相关信息,下次再连接服务器Git库时就不需要再输入账号和服务器库的名称了

        3. 如果要操作哪个库,需要进入到这个库的目录下,例如操作web库,需要先进入到/git/web这个目录下,然后再进行操作,如果还要克隆其他服务器的Git库,在/git目录下进行克隆,同样的只需要克隆时输入账号密码及库所在的位置,克隆下来之后相应的信息都自动配置到对应库中.git隐藏目录下的相应文件中了

      3. 查看当前库的状态

        1. 进入到要查看库的目录下 ,命令:cd /git/web

        2. 查看当前所在库的状态 ,命令:git status

      4. 将库下的文件纳入到git追踪中

        • 将当前库下某一个文件纳入到git追踪中 , 命令:git add <filename> 例如:git add xxx.config
        • 将当前库下所有的文件都纳入到git追踪中 , 命令:git add .

      5. 向本地库提交变更信息(未同步到服务器上)

        • 命令:git commit -a -m "描述信息"
          • -a:提交此库下所有的文件
          • -m:此次提交的信息,为什么要提交,修改了什么等

      6. 本地库变更同步到服务器

        • 命令:git push origin master 提交之前需要将服务器最新的变更下载下来,然后在最新的上面进行修改,修改好之后再提交

      7. 将服务器上的新变更下载到本地

        • 命令:**git pull **
      8. 查看所有版本信息

        • 命令:**tig ** 需要安装这个命令,在库目录下运行
      9. 撤销对文件的变更

        • 命令:git checkout <file> 撤销最近一次的修改
        • 命令:git checkout <hash> 临时回退到一个版本,用tig命令查看各个历史版本的hash值
        • 命令:git checkout matser 退出临时回退,回到最新的版本
      10. 回滚版本

        • git revert master <hash> --no-commit 只是将某个版本的变更给取消掉,不影响后边的版本变更(而不是回到那个版本下的所有情况),--no-commit不提交,如果不加这个参数在回滚是会强制要求commit
      11. 比较一个文件两个版本的不同之处

        • 命令:git diff <file>
    • 例子:将Apache配置文件放到git库中进行版本管理

      • 将配置文件用git做版本管理的好处是:如果某一次该配置文件改出错了,就可以利用git快速回滚到以前未出错时的状态
      1. 首先配置好给Apache使用的库(创建本地库或者克隆服务器上的库)
      2. 将Apache配置文件备份一下 ,命令:sudo cp -rp /etc/apache2 /etc/apache2.bak
      3. 将配置文件移到git库中 ,命令:sudo mv /etc/apache2/ /git/apache2/*
      4. 删除etc下的Apache配置目录 ,命令:sudo rm /etc/apache2
      5. 将移到apache2库下的Apache配置文件的属主和数组都改为root (因为默认就是属于root的),命令:find /git/apache2 -name '.?*' -prune -o -exec chown root:root {} +
        • find /git/apache2 -name '.?*':找到apache2库下所有以 . 开头的文件
        • -prune:找到之后将这些文件排除在外
        • -o -exec chown root:root {} +:其余的文件对齐执行chown命令,也就是改变其属主和数组为root
        • 整条命令的意思就是将apache2库下所有的文件属主和数组都改为root,但排除.git这个库配置目录
      6. 将apache2库下的Apache配置文件软链接到/etc/apache2目录下,让Apache服务能够正常读取到配置文件 ,命令:sudo ln -s /git/apache2 /etc/apache2
      7. 重启Apache服务或让Apache重新加载配置文件 ,命令:sudo systemctl restart apache2.servicesudo systemctl reload apache2
      8. 然后在apache2库中修改Apache配置文件即可,使用git相关命令进行提交,出现问题时再使用git相关命令进行回滚

16.3 Github {#163-github}

16.3.1 简介 {#1631-简介}

  • 全球最大的代码托管服务器
  • 注册帐号 https://github.com
  • 免费账号不支持权限控制和隐私保护

16.3.2 使用Git操作Github {#1632-使用git操作github}

  • 克隆Github上的一个库
  • 提交变更到Github
    • 命令:git push -u origin master
  • 将本地一个库同步到Github上一个库
    1. 设置本地库的上游服务器库 ,命令:git remote add origin https://github.com/xxx/xxx.git 设置当前所在本地库的origin,也就是将Github上的xxx库作为此本地库的服务器端
    2. 将Github库最新的先下载到本地库 ,命令:git pull
    3. 提交本地库到Github ,命令:git push origin master
  • 使用SSH方式连接而不是用https
    1. 网页端:"Clone or Download"------"Clone with SSH"
    2. 网页端:"Setting"------"Deploy keys"------"Add" 然后复制一个ssh的公钥上去
    3. git clone git@github.com:xxx/xxx.git 使用ssh方式连接
    4. 其他使用步骤和使用Git一样
  • 其余使用方式和上一节的Git基本一致

16.3.3 创建Github pages {#1633-创建github-pages}

  1. 新建库名为username.github.io username就是你Github的用户名,必须是
  2. 克隆库到本地git clone https://github.com/username/username.github.io
  3. 进入到库目录并放入你想展示的网页文件 ,例如:cd username.github.io && echo "Hello World" > index.html
  4. 将库下的所有文件纳入到git追踪中 ,命令:git add -all
  5. 本地提交变更 ,命令:git commit -m "Initial commit"
  6. 同步到服务器上 ,命令:git push -u origin master
  7. 浏览器访问https://username.github.io

16.4 搭建 GitLab 服务器 {#164-搭建-gitlab-服务器}

16.4.1 简介 {#1641-简介}

  • 命令行的 Git 灵活强大,但人们还是偏爱图形化
  • GitLab 是开源的 Git 库 WEB 界面(包含团队协作工具 GitLab mattermost)
  • 基于 Ruby 语言开发的 WEB 应用程序
  • 所有组建全部打包集成(Postgresql、redis、nginx、logrotate、Sidekiq、Unicorn)
  • 要支持 MySQL 数据库,社区版需要手动安装

16.4.2 社区版安装 {#1642-社区版安装}

  • 安装需求

    • 最小 单核、1GB、适当存储空间(400MB)、100用户以下(建议双核、内存2GB 以上)
  • 社区版网站https://packages.gitlab.com/gitlab/gitlab-ce

  • 安装和配置

    1. 增加Gitlab更新源 ,命令:curl -s https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash 在其社区web页面上有对应的命令

    2. 安装gitlab社区版 ,命令:sudo apt install gitlab-ce

    3. 自动进行初始化配置 ,命令:sudo gitlab-ctl reconfigure

    4. 查看gitlab运行状态 ,命令:sudo gitlab-ctl status

    5. 配置 ,命令:sudo vim /etc/gitlab/gitlab.rb 每次修改这个配置文件之后都要运行:sudo gitlab-ctl reconfigure

      external_url 'http://gitlab.example.com'	# 外部访问的url地址
      
      # Let's Encrypt 配置,默认没有启用
      # 要使用的话提前把相应参数配置好,然后在运行初始化配置命令sudo gitlab-ctl reconfigure时就会自动向Let's Encrypt申请、下载、使用证书
      ################################################################################
      # letsencrypt['enable'] = nil
      # letsencrypt['contact_emails'] = [] # This should be an array of email addresses to add as contacts
      # letsencrypt['group'] = 'root'
      # letsencrypt['key_size'] = 2048
      # letsencrypt['owner'] = 'root'
      # letsencrypt['wwwroot'] = '/var/opt/gitlab/nginx/www'
      # See http://docs.gitlab.com/omnibus/settings/ssl.html#automatic-renewal for more on these sesttings
      # letsencrypt['auto_renew'] = true
      # letsencrypt['auto_renew_hour'] = 0
      # letsencrypt['auto_renew_minute'] = nil # Should be a number or cron expression, if specified.
      # letsencrypt['auto_renew_day_of_month'] = "*/4"
      
      ##! Turn off automatic init system detection. To skip init detection in
      ##! non-docker containers. Recommended not to change.
      # package['detect_init'] = true
      ################################################################################
      
      ################################################################################
      ## GitLab Geo Secondary (EE only)    配置自己数据库,而不用gitlab安装时默认使用的数据库
      ################################################################################
      # geo_secondary['auto_migrate'] = true
      # geo_secondary['db_adapter'] = "postgresql"
      # geo_secondary['db_encoding'] = "unicode"
      # geo_secondary['db_collation'] = nil
      # geo_secondary['db_database'] = "gitlabhq_geo_production"
      # geo_secondary['db_pool'] = 10
      # geo_secondary['db_username'] = "gitlab_geo"
      # geo_secondary['db_password'] = nil
      # geo_secondary['db_host'] = "/var/opt/gitlab/geo-postgresql"
      # geo_secondary['db_port'] = 5431
      # geo_secondary['db_socket'] = nil
      # geo_secondary['db_sslmode'] = nil
      # geo_secondary['db_sslcompression'] = 0
      # geo_secondary['db_sslrootcert'] = nil
      # geo_secondary['db_sslca'] = nil
      # geo_secondary['db_fdw'] = true
      
      ################################################################################
      ## GitLab Geo Secondary Tracking Database (EE only)
      ################################################################################
      # geo_postgresql['enable'] = false
      # geo_postgresql['ha'] = false
      # geo_postgresql['dir'] = '/var/opt/gitlab/geo-postgresql'
      # geo_postgresql['data_dir'] = '/var/opt/gitlab/geo-postgresql/data'
      # geo_postgresql['pgbouncer_user'] = nil
      # geo_postgresql['pgbouncer_user_password'] = nil
      ##! `SQL_USER_PASSWORD_HASH` can be generated using the command `gitlab-ctl pg-password-md5 gitlab`
      # geo_postgresql['sql_user_password'] = 'SQL_USER_PASSWORD_HASH'
      ################################################################################
      
      ### Email Settings    Email 设置
      ### 给邮箱发送验证码(注册时等)
      # gitlab_rails['gitlab_email_enabled'] = true
      # gitlab_rails['gitlab_email_from'] = 'example@example.com'
      # gitlab_rails['gitlab_email_display_name'] = 'Example'
      # gitlab_rails['gitlab_email_reply_to'] = 'noreply@example.com'
      # gitlab_rails['gitlab_email_subject_suffix'] = ''
      
    6. 显示已经生效的配置 ,命令:sudo gitlab-ctl show-config

    7. 浏览器访问:http://ip,设置初始 root 账号密码

  • 常用命令

    • sudo gitlab-ctl start 启动Gitlab
    • sudo gitlab-ctl stop 停止Gitlab
    • sudo gitlab-ctl restart 重启Gitlab
    • sudo gitlab-ctl tail 查看所有日志
    • sudo gitlab-ctl tail nginx/gitlab_acces.log 查看 nginx 访问日志
    • sudo gitlab-ctl tail postgresql 查看 postgresql 日志

16.4.3 必要配置 {#1643-必要配置}

  • 新建用户账号

    • 管理员登陆 ------ 扳手图标(全局设置)------ 用户

  • 建库

    • 设置 ------ 库成员、clone、同步

  • 管理员 用户设置------Profile(必要)

    • 邮件、名称(显示给别人看)

  • 更改管理员账号名称(必要)

    • Account------root------lw

  • SSH Key

    1. ssh-keygen ------ ~/.ssh/id_rsa.pub

    2. Add key

  • 限制 / 禁用开放用户注册(必要)

    1. 管理员登陆 ------ 扳手图标(全局设置)------ Setting
    2. Sign-up Restrictions ------ Sign-up enabled (不选中)
    3. Send confirmation email on sign-up ------ 域名白名单

  • 禁止普通账户建库(必要)

    • 默认用户可创建 10000 个库(Project)
    • Account and Limit Settings ------ Default projects limit ------ 0

  • Let's Encrypt 证书自动刷新

    • 命令:sudo vim /etc/gitlab/gitlab.rb
    letsencrypt['auto_renew_hour'] = "12"			# 每12个小时
    letsencrypt['auto_renew_minute'] = "30"			# 每30分钟
    letsencrypt['auto_renew_day_of_month'] = "*/7"	# 每7天
    letsencrypt['auto_renew'] = false				# 禁用自动更新(不建议)
    

第 17 章 备份还原 {#第-17-章-备份还原}

17.1 备份还原基础 {#171-备份还原基础}

17.1.1 概述 {#1711-概述}

  • 不管你自是视为如何的电脑高手,都免不了一是犯晕
  • 案例
    • 误操作
    • 勒索病毒
    • 软硬件故障
  • 备份与公司机密
    • 免费云盘
  • 备份是免于损失的有效手段
  • 防火防盗防自己
    • 保持良好睡眠
  • 版本管理也可视为一种备份(上下文不同)

17.1.2 如何备份 {#1712-如何备份}

  • what to backup
    • 数据、配置、操作系统、运行环境
  • where to back
    • 本地、远程、异地三个副本
    • 磁盘、光盘、磁带、一次性写入介质
  • how to restore it
    • 备份系统自动恢复
    • 人工手动恢复

17.2 脚本自动备份 {#172-脚本自动备份}

17.2.1备份计划 {#1721备份计划}

  • 一两个月为周期滚动备份
    • 每月1日执行月备份
    • 每周六执行周备份
    • 每天进行日备份
    • 6个日备份 + 4个周备份 + 2个月备份
    • ./backup.sh
      • 缺陷
        • 每个备份都是完整备,备份时间长,磁盘空间占用量大

17.2.2 备份脚本 {#1722-备份脚本}

  • 创建shell脚本,例如:下面这个只是很简单的备份脚本,实际中按自己的备份计划进行编写

    #!/bin/bash
    ######################
    # 备份脚本
    ######################
    # 备份源
    backup_files="/opt/google"
    # 备份目标
    dest="/backup"
    # 创建归档文件
    day=$(date +%Y-%m-%d-%A-%T)
    hostname=$(hostname -s)
    archive_file="$hostname-$day.tgz"
    # 显示备份状态
    echo "Backing up $backup_files to $des/$archive_file"
    date
    # 执行备份
    tar czPf $dest/$archive_file $backup_files
    

17.2.3 周期执行备份脚本 {#1723-周期执行备份脚本}

  • 使用contab周期执行脚本,编辑contab全局配置文件(/etc/contab)

    32 20 * * * root bash /home/lw/backup.sh	# 每天的20:32以root账号运行后面的命令
    # 第一列:m: 分钟(0-59)			# /2 每两分钟,以此类推
    # 第二列:h: 小时 (0-23)
    # 第三列:dom: 日期(1-31)
    # 第四列:mon: 月份(1-12)
    # 第五列:dow: 星期(0-7)
    # 第六列:user:执行命令用哪个账号
    # 后面的所有列:command: 要执行的命令
    
  • 也可以执行命令:crontab -e 单个账号配置定时任务,不需要再加上面的第六列了

17.3 Rsync {#173-rsync}

17.3.1 简介 {#1731-简介}

  • Linux 下众多备份工具,只rsync是必须掌握的一个
  • 在两个目录或两个主机之间同步文件
  • 从源同步到目标,但不双向同步
  • 支持增量备份,节省时间带宽源
  • 参数众多
  • 学习时建议使用例子文件
    • 使用不当可能破坏文件

17.3.2 使用 {#1732-使用}

  • 常用参数

    | 参数 | 含义 | |-------------------------|---------------------------------------| | -a=rlptgoD | 等于rlptgoD参数合集,归档,保留修改时间戳、符号链接、权限等元数据 | | -r | 递归拷贝目录内容(不保留权限) | | -l | 拷贝符号链接 | | -p | 保留权限 | | -g | 保留数组 | | -o | 保留属主 | | -D | 保留设备文件 | | -v | 显示详细信息 | | -z | 压缩 | | -P | 生成进度文件,实现进程报告和断点续传 | | -e | 指定远程shell类型,默认rsync明文传输数据 | | --exclude filename | 指定排除的文件名,可以使用通配符,如:dir* dir开头的都排除,下同 | | --exclude-from filename | 排除filename这个文件中存储的所有特征文件名(批量排除) | | --include filename | 指定包含的文件名 | | --include-from filename | 包含filename这个文件中存储的所有特征文件名(批量包含) | | --delete | 删除服务器文件,同步时客户端也将对应文件删除(默认不同步删除动作) | | --backup | 删除/覆盖前备份源文件(改名防覆盖) | | --backupdir | 指定备份路径(--backup参数的备份文件) | | --remove-source-files | 成功传输后删除来源文件 | | --dry-run | 模拟执行命令,并输出结果(并不真正修改文件) |

  • 从服务器下载(增量方式)

    • 命令:**rsync -azP -e ssh lw@192.168.2.231:~/sampledir/ ~/backup/ ** 将192.168.2.231这台主机上的lw账号主目录下的sampledir目录下的所有文件通过增量的方式下载到本机当前账号主目录下的backup目录下

      • 参数

        • ~/sampledir/:下载sampledir目录下的所有文件,如果sampledir后面不带 / 则同步sampledir目录

        • ~/sampledir:将sampledir目录及目录下的所有文件下载下来

      • 细节

        • ssh连接方式可以用基于密钥(方便)或密码身份认证
        • sampledir 后的 / 表示拷贝其中所有内容,没有 / 表示拷贝该目录
        • 服务端新增、修改文件后再次运行此命令,只有变更的部分同步
        • 服务器断删除文件后再次运行此命令,客户端不同步删除动作
  • 同步到本地文件夹(增量方式,上传)

    • 命令:sudo rsync /var/log/mysql ~/mysql_log_backup 把/var/log/mysql目录(mysql整个目录)上传到~/mysql_log_backup目录下

17.4 其他备份工具 {#174-其他备份工具}

17.4.1 双向同步工具 {#1741-双向同步工具}

  • 安装,命令:sudo apt install unison
  • 双向同步,命令:unison ~/sampledir ssh://1.1.1.1//home/lw/documents

17.4.2 实时同步工具 {#1742-实时同步工具}

  • 安装,命令:sudo apt install lsyncd
  • 实时监视本地文目录变化
  • 默认使用 Rsync 实现文件同步

17.4.3 SCP / SSHFS {#1743-scp--sshfs}

  • 参考之前的内容

17.5 Bacula {#175-bacula}

17.5.1 简介 {#1751-简介}

  • 基于网络的开源备份、还原、验证软件
  • 对标商业备份软件的功能
  • 客户端支持windows、Linux、Unix、MAC
  • 有多个开源工具组合而成
  • C/S、模块化结构,可单机或分布式部署
  • 最新版支持一次性写入介质和Amazon S3
  • 适合大型环境

17.5.2 软件架构 {#1752-软件架构}

  • Director:主进程,控制所有备份、恢复、验证、归档操作,使用9101端口
  • Console:管理员于 Director 通信的操作接口(传输指令),分为三种类型
    • 基于文本的命令行版本(完全的功能)
    • 基于Gnome GTK+ 的 GUI 版本(大部分功能)
    • wxWidgets GUI 版本(大部分功能)
  • File Daemon:Bacula 客户端程序,安装在需要备份的计算机上,使用9102端口
    • 负责在Director请求时提供文件属性和数据
    • 恢复阶段负责恢复文件属性和数据,以后台进程的形式运行
  • Storage Daemon:读写备份存储介质,执行数据存储和恢复,使用9103端口
  • Catalog:为所有备份文件维护索引和卷数据库
    • 快速定位和恢复归档文件
    • 支持 MySQL、PostgreSQL、SQLite
    • 摘要信息(备份任务、客户端、被备份的文件以及他们存放在哪个卷上)
    • 不存放被备份的文件本身
    • 是bacula区别于简单备份工具的关键
  • Monitor:允许监视Dir、FD和SD(仅GTK+ GUI 可用)

17.5.3 安装 {#1753-安装}

  • 分模块安装,每一个模块都可以安装在不同的机器上

    1. 安装数据库

      1. 命令:sudo apt install bacula-director-pgsql 安装Postgresql并执行连接脚本

      2. 验证是否安装成功

    2. 安装主软件包Director

      1. 命令:sudo apt install bacula-director

      2. 配置让其侦听在网卡的ip上 (默认侦听127.0.0.1),这样别的机器才能连接,命令:sudo vim /etc/bacula/bacula-dir.conf

        # 第一种配置方式:在本机所有网卡上进行侦听
        Director {                            # define myself
          Name = usrv-dir
          DIRport = 9101                # where we listen for UA connections
          QueryFile = "/etc/bacula/scripts/query.sql"
          WorkingDirectory = "/var/lib/bacula"
          PidDirectory = "/run/bacula"
          Maximum Concurrent Jobs = 20
          Password = "Wz84JqLX9biHRdfau6EPUv49GzPdwjdQo"         # Console password
          Messages = Daemon
          # DirAddress = 127.0.0.1		# 把这一行注释了就会在本机所有网卡上进行侦听
        }
        
        # 第二种配置方式:在本机某几块网卡上进行侦听
        Director {                            # define myself
          Name = usrv-dir
          # DIRport = 9101                # 如果要在下面单独指定端口那么就要把这个注释掉
          QueryFile = "/etc/bacula/scripts/query.sql"
          WorkingDirectory = "/var/lib/bacula"
          PidDirectory = "/run/bacula"
          Maximum Concurrent Jobs = 20
          Password = "Wz84JqLX9biHRdfau6EPUv49GzPdwjdQo"         # Console password
          Messages = Daemon
          # DirAddress = 127.0.0.1		# 把这一行注释了
          DirAddresses = {				# 配置侦听网卡的端口
          	ip = { addr = 127.0.0.1; port = 9101; }
          	ip = { addr = 192.168.2.247; port = 9101; }
          }
        }
        
      3. 添加要连接的客户端 ,命令:sudo vim /etc/bacula/bacula-dir.conf

        # 配置一个client,如果有多个就写多个下面的配置段
        # 如果服务器也安装了File Daemon,那么必须要在配置文件中配置本机的File Daemon
        Client {
          Name = client-fd			# 要连接的客户端的名字,在客户端配置文件中中查看
          Address = 192.168.2.231	# 客户端的ip
          FDPort = 9102				# 客户端使用的端口
          Catalog = MyCatalog
          Password = "0_xDj-HJRDFZlGV2VcNCNqfniGAV3jyo7"	# 客户端配置文件中定义的密码
          File Retention = 60 days            # 60 days
          Job Retention = 6 months            # six months
          AutoPrune = yes                     # Prune expired Jobs/Files
        }
        
        
      4. 重启服务,使配置生效 ,命令:sudo systemctl restart bacula-director.service

    3. 安装Storage Daemon

      1. 命令:sudo apt install bacula-sd

      2. 配置让其侦听在网卡的ip上 (默认侦听127.0.0.1),这样别的机器才能连接,命令:sudo vim /etc/bacula/bacula-sd.conf

        # 第一种配置方式:在本机所有网卡上进行侦听
        Storage {                             # definition of myself
          Name = usrv-sd
          SDPort = 9103                  # Director's port
          WorkingDirectory = "/var/lib/bacula"
          Pid Directory = "/run/bacula"
          Plugin Directory = "/usr/lib/bacula"
          Maximum Concurrent Jobs = 20
          # SDAddress = 127.0.0.1			# 把这一行注释了就会在本机所有网卡上进行侦听
        }
        
        # 第二种配置方式:在本机某几块网卡上进行侦听
        Storage {                             # definition of myself
          Name = usrv-sd
          # SDPort = 9103                  # 如果要在下面单独指定端口那么就要把这个注释掉
          WorkingDirectory = "/var/lib/bacula"
          Pid Directory = "/run/bacula"
          Plugin Directory = "/usr/lib/bacula"
          Maximum Concurrent Jobs = 20
          # SDAddress = 127.0.0.1			# 把这一行注释了
          SDAddresses = {				# 配置侦听网卡的端口
          	ip = { addr = 127.0.0.1; port = 9103; }
          	ip = { addr = 192.168.2.247; port = 9103; }
          }
        }
        
      3. 重启服务,使配置生效 ,命令:sudo systemctl restart bacula-sd.service

    4. 安装File Daemon(注意这个是在要备份的机器上安装,当然本机也可以安装)

      1. 命令:sudo apt install bacula-fd 如果在服务器上也安装了fd那么会自动配置好相应的连接配置

      2. 配置让其侦听在网卡的ip上 (默认侦听127.0.0.1),这样别的机器才能连接,命令:sudo vim /etc/bacula/bacula-fd.conf

        # 第一种配置方式:在本机所有网卡上进行侦听
        FileDaemon {                          # this is me
          Name = lw-virtual-machine-fd
          FDport = 9102                  # where we listen for the director
          WorkingDirectory = /var/lib/bacula
          Pid Directory = /run/bacula
          Maximum Concurrent Jobs = 20
          Plugin Directory = /usr/lib/bacula
          # FDAddress = 127.0.0.1			# 把这一行注释了就会在本机所有网卡上进行侦听
        }
        
        # 第二种配置方式:在本机某几块网卡上进行侦听
        FileDaemon {                          # this is me
          Name = lw-virtual-machine-fd
          FDport = 9102                  # 如果要在下面单独指定端口那么就要把这个注释掉
          WorkingDirectory = /var/lib/bacula
          Pid Directory = /run/bacula
          Maximum Concurrent Jobs = 20
          Plugin Directory = /usr/lib/bacula
          # FDAddress = 127.0.0.1			# 把这一行注释
          FDAddresses = {				# 配置侦听网卡的端口
          	ip = { addr = 127.0.0.1; port = 9102; }
          	ip = { addr = 192.168.2.247; port = 9102; }
          }
        }
        
      3. 配置允许连接的服务器和连接时使用的密码 ,命令:sudo vim /etc/bacula/bacula-fd.conf

        # 配置允许连接的Director
        Director {
          Name = usrv-dir		# 允许Director的名字是这个来连接,可以在服务器端的Director配置文件中查看到name,然后将name写到这
          Password = "AcAFW-TNd4pObLeSwHD92WT17d5HmCp38"	# Director过来连接时要提供这个密码才允许连接
        }
        
        # 配置将工作的结果发给谁
        Messages {
          Name = Standard
          director = usrv-dir = all, !skipped, !restored	# 后面写Director的名字(usrv-dir)
        }
        
      4. 重启服务,使配置生效 ,命令:sudo systemctl restart bacula-fd.service

    5. 安装Console

      1. 命令:sudo apt install bacula-console
      2. 使用命令:sudo bconsole 进入bacula命令行下

17.5.4 概念 {#1754-概念}

  • Directive:指令,配置文件中定义资源中的语句或记录
  • 差异备份:基于上一次完整备份后发生变化的内容
  • 增量备份:基于上一次完整、增量、差异备份之后的变化
  • 备份任务 JOB(备份、还原、验证)
    • FileSet:备份什么
    • Clien:备份谁(计算机)
    • Schedule:备份时间(周期)、备份类型(每周一全备,其余增量)
    • Pool:往哪备份(一组 Volume)
    • Priority:多个Job使用相同Schedule时,优先级决定谁先执行(数字越小优先级越高)
    • JobDefs:Job模板,定义Job通用默认指令,可被Job定义覆盖
    • 默认包含一个 Catalog 的备份 Job
  • Pools / Volumes / Labels
    • Volumes:一个物理磁带或一个文件,备份数据写入其中
    • Pool:组合的 Volumes
      • 使得备份不受单个卷(磁带)长度的限制
      • 备份时指定使用的 池 作为存储单元
      • Bacula 依次使用池中的 卷,或提示你挂载下一个 卷
    • Pool 资源在 Director 配置文件中定义,但由 Catalog 实际维护
      • 包含组成池的所有卷的信息
    • 可分别创建每日备份池(增量备份)、每周备份池(全备)

17.5.5 备份配置 {#1755-备份配置}

  • 在Director配置文件中配置备份计划 ,命令:sudo vim /etc/bacula/bacula-dir.conf

    #
    # Default Bacula Director Configuration file
    #
    #  The only thing that MUST be changed is to add one or more
    #   file or directory names in the Include directive of the
    #   FileSet resource.
    #
    #  For Bacula release 9.0.6 (20 November 2017) -- ubuntu 18.04
    #
    #  You might also want to change the default email address
    #   from root to your address.  See the "mail" and "operator"
    #   directives in the Messages resource.
    #
    # Copyright (C) 2000-2017 Kern Sibbald
    # License: BSD 2-Clause; see file LICENSE-FOSS
    #
    
    # 定义Director
    Director {                            # define myself
      Name = usrv-dir			# Director的名字
      # DIRport = 9101                # 侦听端口
      QueryFile = "/etc/bacula/scripts/query.sql"
      WorkingDirectory = "/var/lib/bacula"
      PidDirectory = "/run/bacula"
      Maximum Concurrent Jobs = 20
      Password = "Wz84JqLX9biHRdfau6EPUv49GzPdwjdQo"         # Console password
      Messages = Daemon
      # DirAddress = 127.0.0.1		# 侦听ip
      DirAddresses = {				# 定义侦听的ip和端口
        ip = { addr = 127.0.0.1; port = 9101; }
        ip = { addr = 192.168.2.231; port = 9101; }
      }
    }
    
    # 定义Job的模板
    JobDefs {
      Name = "DefaultJob"		# 模板的名称,在Job使用这个名称进行引用这个模板
      Type = Backup				# 类型:备份
      Level = Incremental		# 等级:增量备份
      Client = client-fd		# 对哪个客户端进行备份
      FileSet = "Full Set"		# 文件集:对指定的目录下的所有文件全部备份,Full Set是下面一个配置段
      Schedule = "WeeklyCycle"	# 备份周期,WeeklyCycle是下面定义的一个配置段
      Storage = File1			# 存储:用哪个存储存放备份的任务,File1是下面的一个配置段
      Messages = Standard		# 消息:
      Pool = File				# 使用文件类型的pool
      SpoolAttributes = yes		# 启用各种属性
      Priority = 10				# 优先级,数字越小越优先
      Write Bootstrap = "/var/lib/bacula/%c.bsr"	# 把bacula执行的任务写成一个脚本,方便以后重复执行
    }
    
    
    #
    # Define the main nightly save backup job
    #   By default, this job will back up to disk in /nonexistant/path/to/file/archive/dir
    Job {
      Name = "BackupClient1"	# 这个Job的名称,随意
      JobDefs = "DefaultJob"	# 引用Job模板
      Level = Full				# 重新定义备份等级为全备份,会覆盖模板中的定义
      Client = U18-fd			# 重新定义备份机器,会覆盖模板中的定义
    }
    
    #Job {
    #  Name = "BackupClient2"
    #  Client = usrv2-fd
    #  JobDefs = "DefaultJob"
    #}
    
    #Job {
    #  Name = "BackupClient1-to-Tape"
    #  JobDefs = "DefaultJob"
    #  Storage = LTO-4
    #  Spool Data = yes    # Avoid shoe-shine
    #  Pool = Default
    #}
    
    #}
    
    # Bacula给自己caltlog数据库的备份配置
    # Backup the catalog database (after the nightly save)
    Job {
      Name = "BackupCatalog"
      JobDefs = "DefaultJob"
      Level = Full
      FileSet="Catalog"
      Schedule = "WeeklyCycleAfterBackup"
      # This creates an ASCII copy of the catalog
      # Arguments to make_catalog_backup.pl are:
      #  make_catalog_backup.pl <catalog-name>
      RunBeforeJob = "/etc/bacula/scripts/make_catalog_backup.pl MyCatalog"
      # This deletes the copy of the catalog
      RunAfterJob  = "/etc/bacula/scripts/delete_catalog_backup"
      Write Bootstrap = "/var/lib/bacula/%n.bsr"
      Priority = 11                   # run after main backup
    }
    
    # 恢复类型的Job
    #
    # Standard Restore template, to be changed by Console program
    #  Only one such job is needed for all Jobs/Clients/Storage ...
    #
    Job {
      Name = "RestoreFiles"
      Type = Restore
      Client=usrv-fd
      Storage = File1
    # The FileSet and Pool directives are not used by Restore Jobs
    # but must not be removed
      FileSet="Full Set"
      Pool = File
      Messages = Standard
      Where = /nonexistant/path/to/file/archive/dir/bacula-restores	# 恢复到哪去
    }
    
    # 文件集 
    # List of files to be backed up
    FileSet {
      Name = "Full Set"
      Include {
        Options {
          signature = MD5	# 备份完成后做一个MD5的摘要签名,从而验证文件的完整性
        }
    #
    #  Put your list of files here, preceded by 'File =', one per line
    #    or include an external list with:
    #
    #    File = <file-name
    #
    #  Note: / backs up everything on the root partition.
    #    if you have other partitions such as /usr or /home
    #    you will probably want to add them too.
    #
    #  By default this is defined to point to the Bacula binary
    #    directory to give a reasonable FileSet to backup to
    #    disk storage during initial testing.
    #
        File = /usr/sbin	# 备份这个目录中的文件
      }
    
    #
    # If you backup the root directory, the following two excluded
    #   files can be useful
    #
      Exclude {		# 备份过程中排除这些目录
        File = /var/lib/bacula
        File = /nonexistant/path/to/file/archive/dir
        File = /proc
        File = /tmp
        File = /sys
        File = /.journal
        File = /.fsck
      }
    }
    
    #
    # When to do the backups, full backup on first sunday of the month,
    #  differential (i.e. incremental since full) every other sunday,
    #  and incremental backups other days
    Schedule {
      Name = "WeeklyCycle"
      Run = Full 1st sun at 23:05	# 每个月第一个星期天23:05进行完整备份
      Run = Differential 2nd-5th sun at 23:05	# 每个月第二到五星期天23:05进行差异备份
      Run = Incremental mon-sat at 23:05	# 每个星期的星期一到星期五23:05进行增量备份
    }
    
    # This schedule does the catalog. It starts after the WeeklyCycle
    Schedule {
      Name = "WeeklyCycleAfterBackup"
      Run = Full sun-sat at 23:10		# 星期日到星期六23:10进行全备份
    }
    
    # 给catalog备份任务准备的文件集
    # This is the backup of the catalog
    FileSet {
      Name = "Catalog"
      Include {
        Options {
          signature = MD5
        }
        File = "/var/lib/bacula/bacula.sql"	# 备份这个数据库文件
      }
    }
    
    # 自身Client定义
    # Client (File Services) to backup
    Client {
      Name = usrv-fd
      Address = localhost
      FDPort = 9102
      Catalog = MyCatalog
      Password = "0_xDj-HJRDFZlGV2VcNCNqfniGAV3jyo7"          # password for FileDaemon
      File Retention = 60 days            # 60 days
      Job Retention = 6 months            # six months
      AutoPrune = yes                     # Prune expired Jobs/Files
    }
    
    # 远程的Client定义
    # Client (File Services) to backup
    Client {
      Name = lw-virtual-machine-fd
      Address = 192.168.2.247
      FDPort = 9102
      Catalog = MyCatalog
      Password = "AcAFW-TNd4pObLeSwHD92WT17d5HmCp38"          # password for FileDaemon
      File Retention = 60 days            # 60 days
      Job Retention = 6 months            # six months
      AutoPrune = yes                     # Prune expired Jobs/Files
    }
    
    #
    # Second Client (File Services) to backup
    #  You should change Name, Address, and Password before using
    #
    #Client {
    #  Name = usrv2-fd
    #  Address = localhost2
    #  FDPort = 9102
    #  Catalog = MyCatalog
    #  Password = "0_xDj-HJRDFZlGV2VcNCNqfniGAV3jyo72"        # password for FileDaemon 2
    #  File Retention = 60 days           # 60 days
    #  Job Retention = 6 months           # six months
    #  AutoPrune = yes                    # Prune expired Jobs/Files
    #}
    
    
    # 定义一些虚拟的设备
    # 把File Daemon
    # Definition of file Virtual Autochanger device
    Autochanger {
      Name = File1		# 定义了File1这个存储设备
    # Do not use "localhost" here
      Address = 192.168.2.247		# 侦听网卡真实ip这样别的机器才能够连接
      SDPort = 9103		
      Password = "Q9CwfnbMCqUHUatiobxEuvBvnGNpxUg3e"
      Device = FileChgr1
      Media Type = File1
      Maximum Concurrent Jobs = 10        # run up to 10 jobs a the same time
      Autochanger = File1                 # point to ourself
    }
    
    # Definition of a second file Virtual Autochanger device
    #   Possibly pointing to a different disk drive
    Autochanger {
      Name = File2		# 定义了File1这个存储设备
    # Do not use "localhost" here
      Address = 192.168.2.247		# 侦听网卡真实ip这样别的机器才能够连接
      SDPort = 9103
      Password = "Q9CwfnbMCqUHUatiobxEuvBvnGNpxUg3e"
      Device = FileChgr2
      Media Type = File2
      Autochanger = File2                 # point to ourself
      Maximum Concurrent Jobs = 10        # run up to 10 jobs a the same time
    }
    
    # Definition of LTO-4 tape Autochanger device
    #Autochanger {
    #  Name = LTO-4
    #  Do not use "localhost" here
    #  Address = localhost               # N.B. Use a fully qualified name here
    #  SDPort = 9103
    #  Password = "Q9CwfnbMCqUHUatiobxEuvBvnGNpxUg3e"         # password for Storage daemon
    #  Device = LTO-4                     # must be same as Device in Storage daemon
    #  Media Type = LTO-4                 # must be same as MediaType in Storage daemon
    #  Autochanger = LTO-4                # enable for autochanger device
    #  Maximum Concurrent Jobs = 10
    #}
    
    # 定义数据库
    # Generic catalog service
    Catalog {
      Name = MyCatalog
      dbname = "bacula"; DB Address = "localhost"; dbuser = "bacula"; dbpassword = "CpleuDJt5LUP"
    }
    
    # 定义Message
    # Reasonable message delivery -- send most everything to email address
    #  and to the console
    Messages {
      Name = Standard
    #
    # NOTE! If you send to two email or more email addresses, you will need
    #  to replace the %r in the from field (-f part) with a single valid
    #  email address in both the mailcommand and the operatorcommand.
    #  What this does is, it sets the email address that emails would display
    #  in the FROM field, which is by default the same email as they're being
    #  sent to.  However, if you send email to more than one address, then
    #  you'll have to set the FROM address manually, to a single address.
    #  for example, a 'no-reply@mydomain.com', is better since that tends to
    #  tell (most) people that its coming from an automated source.
    
    #
      mailcommand = "/usr/sbin/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula: %t %e of %c %l\" %r"
      operatorcommand = "/usr/sbin/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula: Intervention needed for %j\" %r"
      mail = root = all, !skipped
      operator = root = mount
      console = all, !skipped, !saved
    #
    # WARNING! the following will create a file that you must cycle from
    #          time to time as it will grow indefinitely. However, it will
    #          also keep all your messages if they scroll off the console.
    #
      append = "/var/log/bacula/bacula.log" = all, !skipped
      catalog = all
    }
    
    
    #
    # Message delivery for daemon messages (no job).
    Messages {
      Name = Daemon
      mailcommand = "/usr/sbin/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula daemon message\" %r"
      mail = root = all, !skipped
      console = all, !skipped, !saved
      append = "/var/log/bacula/bacula.log" = all, !skipped
    }
    
    # 定义池
    # Default pool definition
    Pool {
      Name = Default
      Pool Type = Backup
      Recycle = yes                       # Bacula can automatically recycle Volumes
      AutoPrune = yes                     # Prune expired volumes
      Volume Retention = 365 days         # one year
      Maximum Volume Bytes = 50G          # Limit Volume size to something reasonable
      Maximum Volumes = 100               # Limit number of Volumes in Pool
      Label Format = "Default_${Year}_${Month}_${Day}"	# 新增标签,这样每个文件都已Default_年月_日_这样来命名,如果这一天备份了多个那么会在 日 后面自动加上001,002这样来区分
    }
    
    # File Pool definition
    Pool {
      Name = File
      Pool Type = Backup
      Recycle = yes                       # Bacula can automatically recycle Volumes
      AutoPrune = yes                     # Prune expired volumes
      Volume Retention = 365 days         # one year
      Maximum Volume Bytes = 50G          # Limit Volume size to something reasonable
      Maximum Volumes = 100               # Limit number of Volumes in Pool
      Label Format = "Vol_${Year}_${Month}_${Day}"	# 新增标签,这样每个文件都已Vol_年月_日_这样来命名,如果这一天备份了多个那么会在 日 后面自动加上001,002这样来区分
    }
    
    
    # Scratch pool definition
    Pool {
      Name = Scratch
      Pool Type = Backup
    }
    
    # 定义Console工具如何连接到Director
    #
    # Restricted console used by tray-monitor to get the status of the director
    #
    Console {
      Name = usrv-mon
      Password = "9cJBC471ueDzIMdx_-UkTX2eHWP5L0BLx"
      CommandACL = status, .status
    }
    
  • 在Storage Daemon中配置 ,命令:sudo vim /etc/bacula/bacula-sd.conf

    Storage {                             # definition of myself
      Name = usrv-sd
      # SDPort = 9103                  # Director's port
      WorkingDirectory = "/var/lib/bacula"
      Pid Directory = "/run/bacula"
      Plugin Directory = "/usr/lib/bacula"
      Maximum Concurrent Jobs = 20
      # SDAddress = 127.0.0.1
      SDAddresses = {
        ip = { addr = 127.0.0.1; port = 9103; }
        ip = { addr = 192.168.2.231; port = 9103; }
      }
    }
    
    #
    # List Directors who are permitted to contact Storage daemon
    #
    Director {
      Name = usrv-dir
      Password = "Q9CwfnbMCqUHUatiobxEuvBvnGNpxUg3e"
    }
    
    #
    # Restricted Director, used by tray-monitor to get the
    #   status of the storage daemon
    #
    Director {
      Name = usrv-mon
      Password = "tZg1UlamOLsE0ZwqaUd_Ofk7F21haU6Hm"
      Monitor = yes
    }
    
    #
    # Note, for a list of additional Device templates please
    #  see the directory <bacula-source>/examples/devices
    # Or follow the following link:
    #  http://www.bacula.org/git/cgit.cgi/bacula/tree/bacula/examples/devices?h=Branch-7.4
    #
    
    #
    # Devices supported by this Storage daemon
    # To connect, the Director's bacula-dir.conf must have the
    #  same Name and MediaType.
    #
    
    # 定义Storage Daemon如何使用设备
    #
    # Define a Virtual autochanger
    #
    Autochanger {
      Name = FileChgr1
      Device = FileChgr1-Dev1, FileChgr1-Dev2	# 使用了这两个具体的设备
      Changer Command = ""
      Changer Device = /dev/null
    }
    
    Device {
      Name = FileChgr1-Dev1
      Media Type = File1	
      Archive Device = /backup1		# 备份文件存放的目录,目录的属主和属组要是bacula
      LabelMedia = yes;                   # lets Bacula label unlabeled media
      Random Access = Yes;
      AutomaticMount = yes;               # when device opened, read it
      RemovableMedia = no;
      AlwaysOpen = no;
      Maximum Concurrent Jobs = 5
    }
    
    Device {
      Name = FileChgr1-Dev2
      Media Type = File1
      Archive Device = /backup2		# 备份文件存放的目录,目录的属主和属组要是bacula
      LabelMedia = yes;                   # lets Bacula label unlabeled media
      Random Access = Yes;
      AutomaticMount = yes;               # when device opened, read it
      RemovableMedia = no;
      AlwaysOpen = no;
      Maximum Concurrent Jobs = 5
    }
    
    #
    # Define a second Virtual autochanger
    #
    Autochanger {
      Name = FileChgr2
      Device = FileChgr2-Dev1, FileChgr2-Dev2
      Changer Command = ""
      Changer Device = /dev/null
    }
    
    Device {
      Name = FileChgr2-Dev1
      Media Type = File2
      Archive Device = /nonexistant/path/to/file/archive/dir
      LabelMedia = yes;                   # lets Bacula label unlabeled media
      Random Access = Yes;
      AutomaticMount = yes;               # when device opened, read it
      RemovableMedia = no;
      AlwaysOpen = no;
      Maximum Concurrent Jobs = 5
    }
    
    Device {
      Name = FileChgr2-Dev2
      Media Type = File2
      Archive Device = /nonexistant/path/to/file/archive/dir
      LabelMedia = yes;                   # lets Bacula label unlabeled media
      Random Access = Yes;
      AutomaticMount = yes;               # when device opened, read it
      RemovableMedia = no;
      AlwaysOpen = no;
      Maximum Concurrent Jobs = 5
    }
    
    #
    # Send all messages to the Director,
    # mount messages also are sent to the email address
    #
    Messages {
      Name = Standard
      director = usrv-dir = all
    }
    

17.5.6 Console常用命令 {#1756-console常用命令}

  • 运行备份

    1. 命令:sudo bconsole 进入bconsole

    2. run 运行备份任务

    3. BackupClient1 选择要执行的备份任务

  • 查看状态

    • status
  • 列出任务

    • list jobs
  • 查看消息

    • message
  • 退出bconsole

    • q

第 18 章 虚拟化 {#第-18-章-虚拟化}

18.1 云计算与虚拟化 {#181-云计算与虚拟化}

18.1.1 云计算 {#1811-云计算}

  • 现代社会生产生活都需要资源
    • 工业社会水电资源
  • 资源的获取方式
    • 靠天吃饭
    • 靠人集中、分散的生产资源(成本、浪费)
    • 自己发电、自己筑坝
  • 信息时代计算资源是最主要的生产力
    • 主机时代、网络时代
    • 集中和分散,三十年河东三十年河西
    • 量子计算可能颠覆一切
  • 计算资源的云化
    • 按需调度、按需索取
    • 计算资源需要更大程度的颗粒度细化
    • 虚拟化是计算资源细分的基础
  • 处理器运算能力的大幅提升
    • 处理速度越来越快(摩尔定律)
    • 多核处理器架构
    • 大量计算资源限制浪费,企业整体运营成本高
    • 多应用同机部署,应用隔离差,稳定性影响大
    • 处理器支持虚拟化技术
  • 常用云计算技术
    • SaaS:Software as a Service
      • 软件即服务,服务以软件形式交付
      • Gmail / Google Docs / 在线 Office
      • 无需本地安装部署
    • PaaS:Platform as a Service
      • 平台即服务
      • 提供软件开发运行的基础平台
      • API、Google App Engine
    • IaaS:Infrastructure as a Service
      • 基础架构即服务
      • 最底层的云计算,物理的计算、存储、网络资源访问
      • AWS 、Google Compute Engine、阿里云
  • 云计算是将资源打碎、分配、发布、交付的一组工具的合集
  • Hypervisors
    • KVM、XEN、QEMU、VirtualBox、VMWare
  • 云计算平台
    • Openstack
  • 服务编排工具
    • Juju
  • 机器配置工具
    • MAAS

18.1.2 虚拟化 {#1812-虚拟化}

  • 降低成本、提高利用率、方便管理部署、快速恢复还原
  • 普遍用于开发测试实验、生产环境部署都可
  • 需要硬件支持(BIOS设置开启)
  • CPU 特性 Hypervision

18.2 KVM {#182-kvm}

18.2.1 简介 {#1821-简介}

  • Kernel-based Virtual Machine
    • 基于内核的虚拟机(KVM)和快速仿真器(QEMU)组成的虚拟化套件(QEMU/KVM)
    • QEMU/KVM 在没有硬件虚拟化支持下,虚拟机需要运行在QEMU模拟器中
    • 有硬件虚拟化支持下,接近硬件物理机速度运行
    • 虚拟化扩展决定性能(virtualization extensions)
    • Ubuntu 默认内建支持的虚拟化方案
    • 内建于Linux内核(Intel 的 kvm-intel.ko 或 AMD 的 kvm-amd.ko)
    • libvirt 库是 Linux 与虚拟化通信的统一接口
    • 处理在主机和客户机之间分离任务所需的低级指令
    • 无法并行运行 VirtualBox 和 KVM虚拟机,它们会抢占CPU的虚拟化功能

18.2.2 验证Cpu是否支持虚拟化 {#1822-验证cpu是否支持虚拟化}

  • 四种方法

  • egrep -c '(vmx|svm)' /proc/cpuinfo

    • 结果不为 0 即为支持

  • kvm-ok

    • 安装命令:sudo apt install cpu-checker

  • lscpu

    • Virtualization:VT-x
    • Flags:vmx

  • sudo virt-host-validate

    • 安装命令:sudo apt install libvirt-clients
    • Checking for hardware virtualization:PASS

18.2.3 服务端安装 {#1823-服务端安装}

  1. 安装软件包 ,命令:sudo apt install bridge-utils libvirt-bin qemu-kvm qemu-system

    • 安装完成之后当前的账号会被自动加入到安装过程中创建的libvirt组账号中,从而使当前账号具有了管理虚拟机的权限
    • 需要重启系统使权限生效
    • 虚拟机镜像文件会放在**/var/lib/libvirt/images/**目录下

    | 软件包 | 功能 | |--------------|------------------------| | bridge-utils | 实现KVM虚拟机网卡桥接功能,默认是NAT的 | | libvirt-bin | Linux与底层虚拟化之间的接口库 | | qemu-kvm | KVM软件包 | | qemu-system | 依赖软件包 |

  2. KVM主配置文件/etc/libvirt/libvirtd.conf,一般不用修改配置文件

18.2.4 图形化客户端 {#1824-图形化客户端}

  1. 安装,命令:sudo apt install virt-manager

  2. 运行

  3. 进行安装管理等操作

  • 如果要连接到远程的KVM需要安装:sudo apt install ssh-askpass ,这个软件的功能是当通过SSH远程连接KVM服务器时会跳出一个提示框给输入密码

18.2.5 KVM日常管理 {#1825-kvm日常管理}

  • 网卡桥接配置

    • 简介

      • 默认虚拟机网络模式为 NAT

        • 可以访问外部网络,但外部计算机无法访问虚拟机
        • 使用网桥实现KVM被外部网络访问

    • 配置网桥

      1. 首先确保安装了网桥工具(bridge-utils),然后编辑配置文件,命令:sudo vim /etc/netplan/01-network-manager-all.yaml

        # Let NetworkManager manage all devices on this system
        network:
          version: 2
          renderer: NetworkManager
          ethernets:
            ens33:			# 关闭dhcp让网卡没有ip地址
              dhcp4: no
              dhcp6: no
          bridges:			# 配置网桥
              br0:
                interfaces: [ens33]	# 让网卡通过网桥上网
                dhcp4: no
                addresses: [192.168.2.247/24]
                gateway4: 192.168.2.1
                nameservers:
                  addresses: [8.8.8.8,8.8.4.4]
        
      2. 使配置生效 ,命令:sudo netplan apply

      3. 在虚拟机中配置桥接模式

  • 克隆创建虚拟机

    • KVM不支持模板功能,但可将VM关机作为模板使用

18.2.6 命令行管理 {#1826-命令行管理}

  • 命令行创建虚拟机

    • 命令:sudo virt-install -n web -r 2048 --disk path=/var/lib/libvirt/images/web.img,bus=virtio,size=10 -c ubuntu-18.04-live-server-amd64.iso --network network=default,model=virtio --graphics vnc,listen=0.0.0.0 --noautoconsole -v

      | 参数 | 含义 | |------------------------------------------------|----------------------| | -n web | 指定虚拟机的名字 | | -r 2048 | 指定虚拟机内存为2GB | | --disk path=/var/lib/libvirt/images/web.img | 指定镜像文件位置 | | bus=virtio | 网络总线类型 | | size=10 | 硬盘大小为10GB | | -c /bak/iso/ubuntu-18.04-live-server-amd64.iso | 安装光盘文件 | | network=default,model=virtio | 使用默认的网络 | | --graphics vnc,listen=0.0.0.0 | 图形化使用VNC,并侦听在所有网卡ip上 | | --noautoconsole -v | 不自动连接虚拟机控制台 |

  • 克隆虚拟机

    • 命令:sudo virt-clone -o web -n db -f /var/lib/libvirt/images/db.img

      | 参数 | 含义 | |-----------------------------------|------------| | -o web | 克隆web这台虚拟机 | | -n db | 新建db虚拟机 | | -f /var/lib/libvirt/images/db.img | 镜像文件存放位置 |

  • 连接KVM服务器

    • 命令:virsh connect qemu:///192.168.2.231
  • 查看所有VM

    • 命令:virsh list 显示所有正在运行的虚拟机
    • 命令:virsh list --all 显示所有虚拟机
  • 管理VM

    • 进入console ,命令:virsh console vm01
    • 退出console ,快捷键:Ctrl + ]
  • 正常关机VM

    • 命令:virsh shutdown vm01
  • 强制关机

    • 命令:virsh destroy vm01
  • 删除虚拟机

    • 命令:virsh undefine vm01
  • 挂起 VM(界面被冻结不关机)

    • 命令:virsh suspend vm01
  • 恢复挂起

    • 命令:virsh resume vm01

18.2.7 使用云镜像 {#1827-使用云镜像}

  • 官方发布的虚拟机

  • 使用步骤

    1. 下载云镜像文件 ,例如:wget http://cloud-images.ubuntu.com/releases/bionic/release/ubuntu-18.04-server-cloudimg-amd64.img -O u18.img.dist

    2. 解压下载的云镜像文件 ,命令:qemu-img convert -O qcow2 u18.img.dist u18.img

    3. 创建用户数据文件

      1. 创建配置文件 ,命令:vim cloud-config

        # cloud-config
        password: 123456	# 设置登录密码,因为默认云镜像文件没有密码,没有密码就登录不上去
        chpasswd: { expire: False }	# 设置密码永不过期
        ssh_pwauth: True	# 运行ssh进行身份认证登录
        
      2. 官生成用户数据盘 ,命令:cloud-localds user-data.img cloud-config 使用cloud-config配置创建创建新的数据盘(差异创建)

    4. 启动虚拟机 ,命令:sudo kvm -m 2048 -smp 2 -hda u18.img -hdb user-data.img -net nic -net user,hostfwd=tcp::1810-:22 -nographic

      • 默认账号名:ubuntu,密码就是配置文件中设置的密码

      | 参数 | 含义 | |-----------------------|------------| | -m 2048 | 指定内存2GB | | -smp 2 | 2个Cpu | | -hda u18.img | 第一块硬盘 | | -hdb user-data.img | 第二块硬盘 | | -net nic | 启用网络 | | -net user | 启用默认系统账号 | | hostfwd=tcp::1810-:22 | ssh连接端口为22 | | -nographic | 没有图形化界面 |

    5. 在虚拟机中,删除云镜像初始化脚本 ,命令:sudo apt-get remove cloud-init

    6. 在虚拟机中,给ubuntu账号重新设置密码

    7. 重启之后就可以当做正常的虚拟机使用了

第 19 章 容器 {#第-19-章-容器}

19.1 容器技术介绍 {#191-容器技术介绍}

19.1.1 简介 {#1911-简介}

  • 虚拟化技术变革了数据中心技术
    • 一切都软件定义 SDN
    • 在一个物理机上运行多个VM,切割利用物理机资源
    • 最大的问题是分派给VM系统的资源浪费(1G内存的VM,APP仅用100M)
    • 虽可共享未使用资源,但效率损失较大
  • 容器再次颠覆IT业界
    • 轻量的虚拟化环境(开销小),但不是我们通常意义认为的虚拟机服务器
    • 容器使用宿主机的CPU(VM有自己的CPU)
    • 容器共享宿主机的OS内核和只读库
    • 容器也可实现应用隔离(与VM相同又不同)
    • 可移植(便携)的软件实例,提高部署效率,改变开发方式

19.1.2 什么是容器及优势 {#1912-什么是容器及优势}

  • 什么是容器?
    • 建议将容器看作一个文件系统(而非VM)
    • 在Linux内核里打造的轻便、接近裸机速度的虚拟环境
    • 容器包含一个与宿主一致的文件结构
      • Ubuntu上的容器拥有一致的文件系统,看起来像是VM或物理机
    • 拷贝所有 Ubuntu中的文件,放到一个新的目录中
      • 独立运行二进制程序,而不运行实际的操作系统
      • 应用运行在这个独立的文件系统中,与宿主机隔离
    • 容器只包含应用运行所必需的最小资源集
    • 一个容器倾向于只运行一个应用(也可运行多个)
    • 熟悉之后你会发现自己更喜欢容器,而不是VM
    • 云时代容器技术会得到更多的重视
  • 可移植性
    • 可移植性是容器的另一重大优势,是容器设计的核心技术
    • 保证在不同宿主系统上获得完全相同的开发运行环境
    • VM也可导入导出,但容器移植更简单

19.1.3 容器的发展 {#1913-容器的发展}

  • 容器并非新技术
    • Docker 是目前最火的容器
    • LXC(Linux Container)
  • 虚拟机技术是不是完蛋了?
    • 目前虚拟化更成熟
    • 虚拟化拥有自己独特的优势
    • 生态已经非常成熟(产品、解决方案、管理工具)
    • 某些场景更适合使用虚拟化
    • 会与容器长期共存(多长的长期?)
  • 并非所有应用都可运行于容器中
    • WEB应用或各种服务
    • 容器还出于飞速的进化发展阶段,特性很吸引人,但还远没有一统江湖

19.1.4 常见容器产品 {#1914-常见容器产品}

  • Docker 和 LXD/LXC
    • Docker 目前最火(优秀的市场营销)
      • Docker 利用分层的方法实现容器化
      • 对容器做的所有修改都会产生一个新层,这些层将成为其他容器的依赖基础
    • LXD 源于 LXC(Lex-C)
      • Docker 最早基于 LXC(所有容器技术的鼻祖)
      • LXC 基于控制组实现进程隔离(提高安全性)
      • LXD 最初由Canonical创建,曾经是 Ubuntu 独有(目前使用 snap 包管理)
      • LXD 是对 LXC 的增强提高
        • 支持快照、ZFS、迁移
      • 可认为是LXC在其上增加了额外的管理层和功能
    • Docker vs LXD/LXC
      • LXC 可视为机器容器,更接近VM
      • LXC 基于一个文件系统实现容器化,可以从宿主机系统访问
      • Docker努力地将自己与虚拟机区分开来
      • Docker可视为应用程序容器,提供运行应用程序所需的基础
      • Docker每个任务都运行在单独的层中
    • 该选择 Docker 还是 LXD/LXC
      • 都用,按应用的环境要求选择
      • Docker 可以在Linux、macOS、Windows上运行Docker容器
      • LXC/LXD 几乎可以运行在所有 Linux 发行版上
      • 使用容器服务运行容器,而非自建容器服务器(Amazon ECS)
      • Docker 商业、社区较成功 (Docker Hub)
  • OpenVZ:基于Linux内核的操作系统级虚拟化技术
    • 虚拟的系统示例称
      • containers 容器
      • virtual private servers (VPSs)
      • virtual environments (VEs)
  • FreeBSD jail
    • OS-Level 虚拟化技术
    • 将基于freebsd的系统划分为多个称为 监狱 的独立微型系统
  • WPARs(The AIX Workload partitions)
    • 工作负载分区(OS-Level 虚拟化技术)
  • Solaris Containers
    • solaris zones

19.2 Docker {#192-docker}

19.2.1 简介 {#1921-简介}

  • Docker 是一个开源的容器引擎
  • Docker 容器包含独立运行软件所需的一切
    • 二进制、库、配置文件、脚本、jar 包等
    • 容器之间完全隔离,各自独立的根文件目录
  • Docker 容器有自己的进程空间和网络接口
  • 组件
    • Docker engine:生成监视和管理所有容器
    • Docker Hub:映像库
    • Docker Client:管理工具

19.2.2 安装 {#1922-安装}

  • Docker 引擎只可以直接运行在 Linux系统上
    • 利用Boot2Docker等适配器帮助,使用轻量级Linux vm可在Mac和微软系统上运行
  1. 安装Docker引擎
    1. 查看当前系统位数 ,命令:uname -m Docker仅支持64位系统保障(32位系统可用)
    2. 两种安装方式
      • 第一种安装方式,Ubuntu软件仓库安装方式 ,一般来说版本会老一些,不会是最新的版本,命令:sudo apt install docker.io 为什么叫docker.io,因为Ubuntu软件仓库在这个docker出现之前就有一个叫docker的软件了
      • 第二种安装方式,使用docker官方提供的源进行安装 ,这样安装的版本会是最新的
        1. 安装依赖包 ,命令:sudo apt install apt-transport-https ca-certificates curl software-properties-common
        2. 添加docker官方库 GPG key ,命令:curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 下载公钥,再将公钥加入到本机系统中
        3. 添加docker官方库更新源 ,命令:sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable" deb [arch=amd64]是给这个源起个名
        4. 更新索引 ,命令:sudo apt update
        5. 安装docker软件包 ,命令:sudo apt install docker-ce 安装docker-ce社区版
    3. 查看运行状态 ,命令:sudo systemctl status docker.service
    4. 将当前用户加入 docker 组 ,这样每次运行docker命令时前面就不用加sudo了,命令:sudo usermod -aG docker ${USER}
    5. 重启系统,使权限生效

19.2.3 基本概念 {#1923-基本概念}

  • Docker映像

    • 组成应用程序运行所需的全部文件合集
    • 只读 / 读写 分层结构(每次对映像的修改都通过commit形成一个新层)
    • 容器层 是基于映像可读写的顶层
    • 所有的 Docker 映像都源自一个 基础映像(Debian / Ubuntu / Centos等)
    • 其他的功能模块附加于基础映像形成最终程序

  • Docker images 是构建 Docker container 的基础

  • Docker 层 / 容器层

  • 每个映像有唯一的ID(SHA256生成的前6字节)

    • 命令:docker images 查看本地映像
    • 命令:docker images --no-trunc 查看本地映像,且显示完整的SHA256值
    • REPOSITORY:用户名 / 库名
    • TAG:标签(latest / 其他变种)
    • IMAGE ID:SHA256,默认只显示6字节
    • CREATED:创建日期
    • SIZE:映像大小

    ![](../images/Ubuntu Server/第19章 容器/2-基本命令-3.png)

  • 每个容器也有唯一的ID(SHA256生成的前6字节)

    • 命令:docker run busybox echo "Hello World!" 运行映像
    • docker run -t -i busybox:ubuntu-14.04 运行映像并指定具体的映像和标签,如果没有这个映像会自动下载这个映像
    • 命令:docker ps -a 查看所有运行中的映像

  • Docker Registry

    • 提供开放的映像注册、查找、访问、使用中央位置
    • 官方注册中心提供多重检查校验的高质量映像(可个人自建)
    • 注册用户可以发布自己定制的映像
  • Repository

    • 映像在注册中心里的具体存储位置(命名空间)
    • 注册用户拥有自己的库
  • Docker Hub Registry

    • Docker 社区创建的官方映像库 / 第三方映像分享平台
    • 命令:docker search ubuntu 搜索映像(默认访问地址 index.docker.io)
    • 命令:docker pull ubuntu 下载官方映像(数字签名保,异常告警)
    • 命令:docker pull registry.example.com/myapp 从自建映像库下载映像(自建映像库)

19.2.4 管理使用 {#1924-管理使用}

  • 查看信息

    • 查看版本信息 ,命令:docker version
    • 查看详细信息 ,命令:docker info
  • Docker registry

    • 应用程序仓库(基本linux映像、高级应用程序映像)
  • 搜索映像

    • 命令:docker search centos 例如,搜索centos容器

  • 下载映像

    • 命令:docker pull centos 下载centos容器,默认下载最新版本

    • 命令:docker pull centos -a 下载centos容器,下载所有版本

  • 显示本地映像

    • 命令:docker images

  • 简单启动映像

    • 命令:docker run busybox echo "Hello World!" 启动busybox映像并允许后面的echo命令

  • 删除映像

    • 命令:docker rmi centos:latest 删除映像,: 前面是映像名 : 后面是标签名

  • 删除容器

    • 命令:docker rm ebe36e0fb400 删除容器,指定容器的ID值

  • 查看运行中的容器

    • 命令:docker ps 查看运行中的容器,且容器中当前有运行程序
    • 命令:docker ps -a 查看运行中的容器,不管容器中有没有运行程序
    • 命令:**docker ps --norunc ** 查看运行中的容器,并显示完整的SHA值

  • 交互登陆

    • 命令:docker run -it ubuntu /bin/bash 运行ubuntu映像中的bash,并返回容器中ubuntu的终端

      • 参数
        • -i:交互式的方式
        • -t:终端
      • Ctrl + D 或 exit命令退出容器中的终端窗口,并关闭容器
      • (Ctrl + P)+(Ctrl + Q) 退出容器中的终端窗口,但不关闭容器

    • 命令:docker run --name lw -it ubuntu /bin/bash 创建容器,并指定这个容器的名字为lw

  • 再次启动容器

    • 命令:docker start 8660f94d5c44 启动容器,后面跟容器的ID值或者NAMES值

  • 再次进入容器中的命令行

    • 命令:docker attach luo 进入到容器中的命令行,后面跟容器的ID或者NAMES

  • 重命名容器

    • 命令:docker rename 9e69956ddb89 lulw 重命名容器,前面是容器的ID,后面是重命名的名字

  • 比较容器和创建容器时用的映像之间的变化

    • 命令:docker diff luo 比较变化,后面跟容器的名字或者ID

      • C:修改
      • A:增加
      • D:删除

  • 停止容器运行

    • 命令:docker stop luo 停止容器运行,后面跟容器的名字或者ID

  • 暂停和恢复容器

    • 命令:docker pause luo 暂停容器使用,后面跟容器的名字或者ID
    • 命令:docker unpause luo 恢复容器使用,后面跟容器的名字或者ID

  • 创建新映像

    • 该修改的修改,该配置的配置好了之后将配置好了的docker容器生成映像,方便以后使用,你也可以将生成的映像上传到Docker官方映像存储中心中

    • 命令:docker commit 24e860c41456 luo/ubuntu_web:0.1

      • 24e860c41456:要生成映像的容器的ID,或者名字
      • luo:账号名称,如果要上传到Docker官方库中需要和注册的账号名一致
      • ubuntu_web:生成镜像的名字
      • 0.1:标签值,一般写版本号

  • 后台运行容器

    • 命令:docker run -d luo/ubuntu_web:0.1 /bin/bash -c "while true; do date; sleep 5; done"

      • -d:后台运行
      • /bin/bash -c "while true; do date; sleep 5; done":用创建出的容器运行这个命令或者脚本

  • 查看日志

    • 命令:docker logs luo 查看对应容器的日志,后面跟容器的名字或者ID

19.2.5 案例:安装Apache {#1925-案例安装apache}

  1. 以ubuntu映像创建新的容器 ,命令:docker run --name web -dit -p 8080:80 ubuntu /bin/bash
    • -p 8080:80 将本机的8080端口映射到容器的80端口
  2. 进入到容器的命令行中 ,命令:docker attach web
  3. 然后就和正常安装Apache一样了 ,命令:apt install apache2
  4. 启动Apache ,命令:/etc/init.d/apache2 start
  5. 将Apache配置成随容器的启动而启动
    1. 安装一个文本编辑器,vi、vim、nano都可以,因为默认镜像中没有按住文本编辑器
    2. 编辑/etc/bash.bashrc配置文件,在文件末尾添加/etc/init.d/apache2 start即可
  6. 使用(ctrl+p)+(ctrl+q)退出容器命令行
  7. 使用浏览器访问宿主机的8080端口即可
  8. 可以将配置好的容器生成映像,方便以后使用,命令:docker commit web luo/ubuntu-apache:1.0

19.2.6 自动创建映像 {#1926-自动创建映像}

  • 使用Dockerfiles自动创建映像

    1. 创建 Dockerfiles 文本文件,文件内容就是创建容器的指令,命令:vim Dockerfiles 内容是

      FROM ubuntu		# 使用ubuntu映像创建容器,没有就会自动下载
      MAINTAINER luo <luo@admin.com>	# 维护这个Dockerfiles的人的信息,方便联系
      RUN apt update; apt dist-upgrade -y	# 使用RUN 在创建的容器中运行指定的命令,下同
      RUN apt install -y apache2 vim
      RUN echo "/etc/init.d/apache2 start" >> /etc/bash.bashrc
      
    2. 然后将这个Dockerfiles文件发送给其他人,其他人使用命令:docker build -t test/apache-server:1.0 . 就可以创建出对应的映像了

      • -t test/apache-server:1.0 按Dockerfiles生成映像并命名为test/apache-server:1.0
      • . 在当前目录下找Dockerfiles文件运行,或者指定Dockerfiles所在的目录
    3. 再以Dockerfiles创建的映像运行容器即可

19.3 LXD {#193-lxd}

19.3.2 简介 {#1932-简介}

  • lxd 新部署容器过程比Docker更容易
  • 退出容器时不必以特定的方式退出
  • lxd 容器中没有层的概念
  • Docker中的层可以使部署更快(没有清理也可能感觉混乱)

19.3.2 安装和初始化 {#1932-安装和初始化}

  1. 安装软件包 ,命令:sudo snap install lxd 更新的版本,命令:sudo apt install lxd 相对比较老的版本
  2. 将当前用户加入 lxd 组 ,这样每次运行lxd命令时前面就不用加sudo了,命令:sudo usermod -aG lxd ${USER}
  3. 重启计算机,使权限生效
  4. 首次安装需要进行初始化lxd管理层 ,命令:lxd init 一般一路回车就可以了

19.3.3 管理使用 {#1933-管理使用}

  • 运行容器

    • 命令:lxc launch ubuntu:18.04 luo 创建并运行ubuntu 18.04容器,取名为luo
    • 命令:lxc launch u1810 lu 使用本地镜像创建及运行容器,取名为lu
    • 自动下载映像并创建、运行容器
    • lxd 命令针对 lxd 管理层,容器管理命令仍然使用 lxc
  • 常用管理命令

    • lxc list 列出容器
    • lxc start <container> 启动容器
    • lxc stop <container> 停止容器
    • lxc delete <container> 删除容器
    • lxc image list 列出映像
    • lxc image delete <img_name> 删除映像
  • 交互登录

    • 命令:lxc exec luo bash 以root登录
    • 命令:lxc exec luo -- sudo --login --user ubuntu 以ubuntu账号登录
    • 命令:lxc exec luo -- apt update 直接让容器执行后面的命令,而不登陆进去
    • 使用exit 或 Ctrl + D退出,仅退出不关闭容器与docker不同
  • 设置容器随宿主机启动而启动

    • 命令:lxc config set luo boot.autostart 1
  • 列出远程映像存储服务器

    • 命令:lxc remote list 默认3个

      | 镜像 | 作用 | |--------------|-----------------| | images | 其他 Linux 发行版映像 | | ubuntu | 稳定版 Ubuntu 映像 | | ubuntu-daily | 每日最新的 ubuntu 映像 |

  • 从远程复制映像

    • 命令:lxc launch images:debian/stretch test01 下载映像并使用映像创建test01容器
    • 命令:lxc image copy ubuntu:18.10 local: --alias u1810 从 ubuntu 存储复制映像到 local 存储,并命名为u1810
  • 容器与宿主机上传下载文件

    • 命令:lxc file pull luo/etc/hosts . 下载容器中的hosts文件到当前目录
    • 命令:lxc file push /etc/hosts luo/tmp/ 将宿主机hosts文件上传到容器/tmp目录下
  • 映像自动更新间隔(小时)

    • 命令:lxc config set images.auto_update_interval 24 设置自动更新时间为24小时
  • 自动清除未使用的映像(天数)

    • 命令:lxc config set images.remote_cache_expiry 5 设置自动清除时间为5天
  • 查看配置 ,命令:lxc config show

  • 外网访问容器

    • 防火墙规则路由流量

    • 创建配置文件 DHCP 获取物理网络地址(类似于 VM)

    • 宿主机创建桥接网卡 br0

      1. 编辑配置文件,命令:lxc network edit lxdbr0

        description: External access profile
        devices:
        eth0:
        name: eth0
        nictype: bridged
        parent: br0
        type: nic
        
      2. 命令:lxc profile add luo external

      3. 命令:lxc launch ubuntu:18.04 web01 -p default -p external

第 20 章 群集 {#第-20-章-群集}

20.1 群集技术 {#201-群集技术}

20.1.1 简介 {#2011-简介}

  • 保证业务可用性是一切工作的基础
  • 丧失可用性的安全毫无意义
  • 消灭单点故障隐患是提高可用性的主要手段
  • 从单机、多机再到网络所有节点的冗余
  • 多机实现容错通常被称为集群 / 群集(Cluster)
  • 负载均衡群集 / HA / 服务器群集(关键在于是否同步数据)

20.1.2 原理 {#2012-原理}

  • 服务器集群
    • 共享存储(存储设备价格较贵)
    • 基于块设备复制(趋势、廉价)
  • 群集资源(群集中所有服务器共同享有的一组资源)
    • 域名
    • 地址
    • 存储
    • 硬件
    • 路径
    • 名称
    • 在主机间漂移
  • 主机之间基于块设备复制
  • 保持主机间的数据同步是一切的基础

20.2 DRBD群集 {#202-drbd群集}

20.2.1 简介 {#2021-简介}

  • DRBD --- Distributed Replicated Block Device
    • 分布式块设备复制技术
    • 由 linbit 开源(培训、服务收费)
    • 由 Linux 内核模块 + 用户空间管理工具组成
    • 实现服务器间块设备的同步镜像(粗暴理解:跨主机的 RAID 1)
    • 通常采用主 / 备模式部署(Primary / Slave)
  • 保证数据一致性(协议 / 方法)
    • A:异步复制,本地写成功即确认,发送buffer中的数据可能丢失
    • B:内存同步,本地写入并发送成功即确认,如掉电,则数据丢失
    • C:同步复制,节点全部写入成功后确认
    • C 可最高确保数据同步,但写入时间长,性能处于劣势
  • 清除块设备数据
    • 将准备进行同步的设备或者分区清除原有数据,命令:sudo dd if=/dev/zero of=/dev/sdb1 向sdb1写满0,其余的也要清楚数据

20.2.2 安装 {#2022-安装}

  1. DRBD 安装准备

    1. 创建两台Ubuntu server虚拟机,配置好网络让两个虚拟机之间可以互相访问,并分别为两个虚拟添加一块新硬盘作为到时候进行同步数据的设备(给1G的大小就可以了,这样同步会快一些),两台虚拟机主机名分别为usrv01和usrv02(不要重名)
  2. 配置两台主机域名解析,如果有DNS服务器就在DNS服务器中配置(生产环境中),这里就在hosts文件中配置了,内容如下

    # 分别在两台主机的hosts文件配置主机名到ip地址的对应关系
    192.168.2.35    usrv01
    192.168.2.36    usrv02
    
  3. 安装软件包

    1. 安装ntp服务 ,因为群集正常工作需要各个机器的时间是同步的,命令:sudo apt install ntp
    2. 安装DRBD服务 ,命令:**sudo apt install drbd8-utils ** 现在Ubuntu官方仓库只收录了8这个大版本
      • 安装过程中会要求安装postfix,这是为了当群集发生故障时发送告警邮件,这里就不配置了(实际情况中按实际来)

20.2.3 配置 {#2023-配置}

  • 主配置文件:/etc/drbd.conf,配置目录:/etc/drbd.d/
  1. 修改主配置文件,配置群集(群集中每一台服务器都要进行配置,配置内容相同)

    # You can find an example in  /usr/share/doc/drbd.../drbd.conf.example
    
    # 注释掉下面默认这两行,官方建议在不同的配置文件中配置不同的配置,然后在主配置文件中进行包含,这里群集少就直接在主配置文件中配置了
    # include "drbd.d/global_common.conf";
    # include "drbd.d/*.res";
    
    # 进行自己的群集配置
    global { usage-count no; }		# 不允许DEBD官方收集这台机器的信息
    common { syncer { rate 100M; } }	# 同步数据时的速率,按实际情况设置,这里设置成百兆
    resource r0 {			# 配置磁盘镜像的资源,取名为r0,名称随意
    	protocol C;			# 用C协议,C:同步复制,节点全部写入成功后确认
        startup {			# 启动,设置超时时间多长时间不响应,就去接管那一台服务器磁盘资源的使用权
            wfc-timeout 15;	
            degr-wfc-timeout 60;
        }
        net {				# 同步数据时进行身份认证
            cram-hmac-alg sha1;			# 使用sha1加密密码
            shared-secret "secret";		# 设置密码,这里设置为secret
        }
        # 定义群集资源
        on usrv01 {				# 定义群集第一台服务器
            device /dev/drbd0;		# 定义同步的设备时drbd0这个设备(逻辑上的概念),这一项每个群集服务器都要配置成一样的
            disk /dev/sdb1;			# 具体使用的真实硬盘设备,必须是分区
            address 192.168.2.35:7788;		# 本机的ip和通信使用的端口
            meta-disk internal;		# 磁盘源数据内部互相进行通信
        }
        on usrv02 {				# 定义群集第二台服务器
            device /dev/drbd0;		# 定义同步的设备时drbd0这个设备(逻辑上的概念),这一项每个群集服务器都要配置成一样的
            disk /dev/sdb1;			# 具体使用的真实硬盘设备,必须是分区
            address 192.168.2.36:7788;	# 本机的ip和通信使用的端口
            meta-disk internal;		# 磁盘源数据内部互相进行通信
        }
    }
    
  2. 初始化元数据存储(所有节点都要执行) ,命令:sudo drbdadm create-md r0 r0就是配置文件中配置的名字

  3. 启动服务(所有节点都要执行)

    1. 启动服务 ,命令:sudo systemctl start drbd.service
    2. 设置drbd服务随操作系统自动启动 ,命令:sudo systemctl enable drbd
    3. 启动配置的硬盘资源 ,命令:sudo drbdadm up r0 r0就是配置文件中配置的名字
  4. 指定主节点(在一个节点上执行) ,命令:sudo drbdadm -- --overwrite-data-of-peer primary all

    • 观察同步进程(在另一节点上执行),命令:watch -n1 cat /proc/drbd
  5. 然后就可以测试是否能用了

    1. 查看每个节点的状态
      • 查看本机的块设备,命令:lsblk drbd块设备id时147,这是由国际组织制定的,不同的块设备类型有着不同的编号
      • 查看drbd运行状况,命令:sudo drbd-overview
      • 命令:sudo cat /proc/drbd
    2. 格式化并挂载逻辑设备(配置文件中配置的drbd0逻辑设备),在主节点上执行
      1. 格式化成ext4文件格式 ,命令:sudo mkfs.ext4 /dev/drbd0
      2. 挂载到某个目录,这个目录中的所有数据就会同步到其他节点上了
    3. 测试
      • 将自己变为主节点 ,命令:sudo drbdadm primary r0
      • 将自己变为备用节点 ,命令:sudo drbdadm secondary r0
      • 从备用节点变为主节点需要将逻辑设备(如drbd0)进行挂载
      • 节点主备不会自动切换,需要群集管理器来实现资源的在不同节点间自动切换
      • 不可同时几个节点做主节点并挂载

20.3 pacemaker群集管理器 {#203-pacemaker群集管理器}

20.3.1 简介 {#2031-简介}

  • 集群资源管理器(CRM - Cluster Resource Manager)
  • 开源,适合各种大小(类型)集群管理(主/主、主/备)
  • 基于资源级别的监测和恢复保证应用最大可用性
  • 基础组件(Corosync或Heartbeat)实现集群各成员间通信和关系管理
  • Corosync:消息层组件(心跳传输),管理成员关系、消息和仲裁
  • 可使用共享存储或基于块设备的复制(DRBD)

20.3.2 方式一:使用Corosync {#2032-方式一使用corosync}

  1. 安装pacemaker之前需要将DRBD群集给关闭(所有节点都要执行)

    1. 关闭服务,命令:sudo systemctl stop drbd
    2. 关闭开机自启,命令:sudo systemctl disable drbd
    3. 主节点取消挂载,命令:sudo umount /var/www/html
    4. 关闭硬盘资源,命令:sudo drbdadm down r0
  2. 安装pacemaker ,命令:sudo apt install pacemaker(所有节点都要安装)

  3. 编辑Corosync配置文件 ,命令:sudo vim /etc/corosync/corosync.conf(所有节点都要配置)

    # totem全局配置段
    totem {
    	version: 2
    	cluster_name: ubuntu	# 名称,随意
    	secauth: off			# 是否启用安全的身份认证机制
    	transport: udpu			# 通信方式
    	interface {				# 配置接口
    		ringnumber: 0
    		bindnetaddr: 192.168.2.23	# 群集统一对外提供服务的ip地址,谁是主节点谁得到这个ip,主节点原先的ip不变,会在主节点网卡创建一个子节口把这个ip配置给那个子节点
    		broadcast: yes		# 通信方式广播
    		mcastport: 5405		# 端口
    	}
    }
    # 定义要进行管理节点
    nodelist {
    	node {		# 定义一个节点
    		ring0_addr: 192.168.2.35	# 节点的真实IP地址
    		name: usrv01			# 节点名称
    		nodeid: 1			# 节点id,唯一
    	}
    	node {		# 定义一个节点
    		ring0_addr: 192.168.2.36	# 节点的真实IP地址
    		name: usrv02			# 节点名称
    		nodeid: 2			# 节点id,唯一
    	}
    }
    # 仲裁相关的机制(主节点故障了由谁来顶上去)
    quorom {
    	provider: corosync_votequorum
    	two_node: 1				# 双节点群集
    	wait_for_all: 1
    	last_man_standing: 1
    	auto_tie_breaker: 0
    }
    
  4. 重启服务(所有节点都要执行)

    • 重启Corosync服务,命令:sudo systemctl restart corosync.service
    • 重启pacemaker服务,命令:sudo systemctl restart pacemaker.service
  5. 安装和配置crm管理工具(所有节点都要安装)

    1. 安装crm ,命令:sudo apt install crmsh
    2. 配置和创建群集资源 ,命令:sudo crm configure 进入到crm自己的命令行下,分别执行以下配置
      • property stonith-enabled=false 全局配置项,出现问题的节点是否从集群环境中脱离(所有节点的配置文件中删除),设置为false
      • property no-quorum-policy=ignore 全局配置项,取消仲裁选举,因为当前只有两个节点(一个节点挂了肯定是起另一个节点所以不需要进行选举),集群选举需超半数(至少3节点)
      • primitive drbd_res ocf:linbit:drbd params drbd_resource=r0 op monitor interval=29s role=Master op monitor interval=31s role=Slave 定义磁盘存储资源
        • primitive:通过这个指令来定义磁盘资源
        • drbd_res:现在要创建一个drbd磁盘资源
        • ocf:linbit:drbd:使用这个驱动
        • params:后面指定参数
        • drbd_resource=r0:使用drdb r0这个资源,之前在drdb中配置的资源,如果有多个的话也可以在这里写多个,比如drbd_resource=r0,r1,r2
        • op:可以被操作
        • role=Master monitor interval=29s:主节点监视的间隔是29秒
        • monitor interval=31s role=Slave:备用节点监视的间隔是31秒
      • ms drbd_master_slave drbd_res meta master-max=1 master-node-max=1 clone-max=2 clone-node-max=1 notify=true 创建master/slave群集
        • ms:master/slave
        • drbd_master_slave:由drbd构成的主备
        • drbd_res:drbd的资源
        • meta:metadata元数据
        • master-max=1:主节点最多为1个
        • master-node-max=1:同时为主节点最多为1个
        • clone-max=2:克隆的节点最多有两个
        • clone-node-max=1:并发的同时克隆的节点只能有1个
        • notify=true:允许互相发送状态信息
      • primitive fs_res ocf:heartbeat:Filesystem params device=/dev/drbd0 directory=/var/www/html fstype=ext4 文件系统挂载点
        • primitive:通过这个指令来定义磁盘资源
        • ocf:heartbeat:Filesystem:定义文件心跳、系统
        • params:后面指定参数
        • device=/dev/drbd0:使用这个磁盘设备
        • directory=/var/www/html:挂载的目录
        • fstype=ext4:使用ext4文件系统格式
      • colocation fs_drbd_colo INFINITY: fs_res drbd_master_slave:Master 让主备节点可以互相进行协调工作
      • order fs_after_drbd mandatory: drbd_master_slave:promote fs_res:start 主备节点启动顺序配置
    3. crm命令行下,使用commit提交刚刚的设置
      • show,显示配置信息
      • quit,退出crm命令行
    4. 重启主节点测试自动切换
      1. 重启Corosync服务,命令:sudo systemctl restart corosync.service
      2. 重启pacemaker服务,命令:sudo systemctl restart pacemaker.service

20.3.3 方式二:使用Heartbeat创建MySQL群集 {#2033-方式二使用heartbeat创建mysql群集}

  • 基于 heartbeat 创建 Mysql 群集

    • 主机添加第二块网卡,用作 DRBD 数据复制

  • 以下操作每一台群集的节点主机都要进行操作(特殊说明的除外)

  1. 环境准备

    1. 准备两台虚拟机,命名为db1和db2,为两台主机添加第二块1G的硬盘,添加第二块网卡(第一块网卡对外提供服务,第二块网卡给heartbeat通信用)
      • 第二块网卡通信方式都选择,自定义(U):特定虚拟网络,让第二块网卡互相之间直接通信,真实情况中可以用一根网线将群集的两个节点直接连接起来,这样快(网线一头用568A一头用568B)
    2. 修改两台虚拟机的hostname为db1和db2(需要先将/etc/cloud/cloud.cfg中的preserve_hostname配置项改为true,然后再修改/etc/hostname文件)
    3. 将第二块网卡的IP分别配置成192.168.0.1和192.168.0.2,在/etc/netplan/50-cloud-init.yaml中配置,只需写一个addresses配置项即可,第一块网卡真实情况下要配置成静态IP
    4. 编辑/etc/hosts文件将两台主机的主机名和第二块网卡的ip地址对应关系分别写入到hosts文件中,不需要通过DNS服务器解析,这样会快一点,第一块网卡对外提供服务可以使用DNS解析
    5. 格式化硬盘 ,命令:sudo echo -e 'n\np\n1\n\n\nw' | sudo fdisk /dev/sdb
    6. 重启系统
  2. 安装drbd和heartbeat软件包 ,命令:sudo apt install drbd8-utils heartbeat

    1. 启动drbd和heartbeat服务
      • 命令:sudo systemctl start drbd.service
      • 命令:sudo systemctl start heartbeat.service
    2. 配置drbd和heartbeat服务开机自启
      • 命令:sudo systemctl enable drbd
      • 命令:sudo systemctl enable heartbeat
  3. 配置drbd ,命令:sudo vim /etc/drbd.conf

    # You can find an example in  /usr/share/doc/drbd.../drbd.conf.example
    
    # 注释掉下面默认这两行,官方建议在不同的配置文件中配置不同的配置,然后在主配置文件中进行包含,这里群集少就直接在主配置文件中配置了
    # include "drbd.d/global_common.conf";
    # include "drbd.d/*.res";
    
    # 进行自己的群集配置
    global { usage-count no; }		# 不允许DEBD官方收集这台机器的信息
    common { syncer { rate 100M; } }	# 同步数据时的速率,按实际情况设置,这里设置成百兆
    resource r0 {			# 配置磁盘镜像的资源,取名为r0,名称随意
    	protocol C;			# 用C协议,C:同步复制,节点全部写入成功后确认
        startup {			# 启动,设置超时时间多长时间不响应,就去接管那一台服务器磁盘资源的使用权
            wfc-timeout 15;	
            degr-wfc-timeout 60;
        }
        net {				# 同步数据时进行身份认证
            cram-hmac-alg sha1;			# 使用sha1加密密码
            shared-secret "secret";		# 设置密码,这里设置为secret
        }
        # 定义群集资源
        on db1 {				# 定义群集第一台服务器
            device /dev/drbd0;		# 定义同步的设备时drbd0这个设备(逻辑上的概念),这一项每个群集服务器都要配置成一样的
            disk /dev/sdb1;			# 具体使用的真实硬盘设备,必须是分区
            address 192.168.0.1:7788;		# 本机的ip和通信使用的端口,使用第二块网卡ip地址
            meta-disk internal;		# 磁盘源数据内部互相进行通信
        }
        on db2 {				# 定义群集第二台服务器
            device /dev/drbd0;		# 定义同步的设备时drbd0这个设备(逻辑上的概念),这一项每个群集服务器都要配置成一样的
            disk /dev/sdb1;			# 具体使用的真实硬盘设备,必须是分区
            address 192.168.0.2:7788;	# 本机的ip和通信使用的端口,,使用第二块网卡ip地址
            meta-disk internal;		# 磁盘源数据内部互相进行通信
        }
    }
    
  4. 配置heartbeat,创建并编辑配置文件 ,命令:sudo vim /etc/ha.d/ha.cf

    keepalive 1				# 每隔1秒检查一次是否存活,累计几个检查周期都没有正确响应就确定为发送故障
    deadtime 10				# 确定主节点发生故障后再等待10秒
    initdead 60				# 备用节点启动时的辅助等待延迟,因为启动后还要启服务啥的,否则备用节点刚启动服务还没来得及起就判断备用节点的服务已经挂了
    auto_failback off		# 主节点挂了之后被修好了又加入到群集中是否还要把它设置为主节点(如果主节点的机器性能最好那么设置为on,否则建议设置为off)
    bcast enp0s8			# heartbeat通信接口,设置为第一块网卡,因为第二块网卡是专门给drbd同步数据用的
    node db1				# 指定群集节点1,建议是使用DNS配置的域名进行解析(因为heartbeat用的是第一块网卡),下同
    node db2				# 指定群集节点2
    
  5. 配置群集硬盘资源,创建并编辑配置文件 ,命令:sudo vim /etc/ha.d/haresources

    # 配置db1为主节点,群集的ip地址,使用r0这个磁盘资源,使用drbd0磁盘设备,挂载到/var/lib/mysql目录下,使用ext4文件系统,noatime降低对磁盘没有必要的写操作,mysql是要进行管理的应用(要管理什么应用就写什么应用)
    db1 1.1.1.1/24 drbddisk::r0 Filesystem::/dev/drbd0::/var/lib/mysql::ext4::noatime mysql
    
  6. 配置heartbeat通信时要进行身份认证 ,命令:sudo vim /etc/ha.d/authkeys

    auth1	# 启用身份认证
    1 sha1 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8	# 密码加密方式使用sha1,后面是明文密码sha1加密后的密文
    
    • 出于安全的考虑,设置身份认证文件的权限,命令:sudo chmod 600 /etc/ha.d/authkeys
  7. 在主节点上进行配置

    1. 创建drbd资源 ,命令:sudo drbdadm create-md r0
    2. 重启drbd服务 ,命令:sudo systemctl start drbd.service
    3. 设置主节点 ,命令:sudo drbdadm -- --overwrite-data-of-peer primary all
    4. 把当前节点变为主节点 ,命令:sudo drbdadm primary r0
    5. 格式化磁盘资源 ,命令:sudo mkfs.ext4 /dev/drbd0
    6. 创建要挂载的目录 ,命令:sudo mkdir /var/lib/mysql
  8. 在备用节点上进行配置

    1. 创建drbd资源 ,命令:sudo drbdadm create-md r0
    2. 重启drbd服务 ,命令:sudo systemctl start drbd.service
    3. 创建要挂载的目录 ,命令:sudo mkdir /var/lib/mysql
    4. 等待硬盘同步完成
      • 查看同步进度,命令:watch -n1 cat /proc/drbd
  9. 重启heartbeat服务(所有节点) ,命令:sudo systemctl restart heartbeat.service

  10. 测试群集配置是否成功

    • 查看主节点ip有没有群集中配置的ip,命令:ip a
    • 查看drbd中配置的逻辑磁盘设备有没有被挂载成功,命令:sudo mount | grep drbd0
  11. 安装和配置MariaDB

    1. 安装MariaDB ,命令:sudo apt install mariadb-server
    2. 进行安全设置 ,命令:sudo mysql_secure_installation
  12. 禁用 MariaDB服务自动启动,服务启动控制权交给群集 ,命令:sudo systemctl disable mysql

  13. 在备用节点上执行

    1. 停止备用节点MariaDB服务,命令:sudo systemctl stop mariadb.service
    2. 清除/var/lib/mysql/目录下的所有数据,因为这里的数据应该是由主节点传过来的,命令:sudo rm -rf /var/lib/mysql/*
    3. 修改MariaDB侦听ip不为127.0.0.1而为网卡真实ip,命令:sudo sed -i 's/127.0.0.1/0.0.0.0/g' /etc/mysql/mariadb.conf.d/*.cnf
  14. 在主节点上执行

    1. 对MariaDB进行配置,命令:sudo mysql

      CREATE USER 'root'@'192.168.123.%' IDENTIFIED BY 'password';	-- 创建root账号,只允许192.168.8这个网段的来连接
      GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.123.%' WITH GRANT OPTION;	-- 赋予权限
      FLUSH PRIVILEGES;	-- 刷新权限
      QUIT;	-- 推出MariaDB命令行
      
    2. 修改MariaDB侦听ip不为127.0.0.1而为网卡真实ip,命令:sudo sed -i 's/127.0.0.1/0.0.0.0/g' /etc/mysql/mariadb.conf.d/*.cnf

  15. 重启heartbeat服务(所有节点,不要同时重启主备节点间隔30秒左右) ,命令:sudo systemctl restart heartbeat.service

  16. MySQL群集已经搭建完成,进行测试即可

    1. 用其他机器连接群集,创建数据库
    2. 重启主节点或者重启主节点heartbeat服务模拟主节点出现故障
    3. 再用其他机器连接群集,查看刚刚创建的数据库是否还在

第 21 章 LDAP {#第-21-章-ldap}

21.1 目录服务 {#211-目录服务}

21.1.1 简介 {#2111-简介}

  • 不同于文件系统的目录(D/d)
  • 目录服务是企业网络的核心基础架构
    • 如此重要的服务并不被大多数熟悉
    • 很少独立使用,与其他服务结合使用
    • 微软的企业战略(埋坑)
    • 每一本书都有自己的目录
  • 数据集中存储的应用需求
    • 集中存储、集中管理、集中定位
    • 身份认证、公钥分发、邮件路由、地址查询、应用配置、单点登陆(SSO)
    • 面向大量频繁的数据查询操作,少量写操作(基本不变的数据)
    • 权限限制授权用户查询

21.1.2 作用 {#2112-作用}

  • 用户认证
  • 机器认证
  • 用户和组
  • 电话地址簿
  • 组织呈现
  • 资产跟踪
  • 集中应用配置
  • PBX / 网络设备配置

21.1.3 架构 {#2113-架构}

  • 软件架构
    • 不同于 SQL 的后端层级化数据库(主要面向查询操作)
    • 与 DNS 的分布式结构更接近,命名上通常保持一致
    • 数据库基于键值对的方式存储数据
    • 标准统一的服务前端应用查询访问接口(OSI X.500)
    • 统一的客户端查询组件和协议(C/S)
    • 支持通信会话加密
    • Directory information tree(DIT)
  • 与自建数据库开发相比
    • 专门针对查询服务的数据库结构类型
    • 统一标准的查询接口及通信协议(DAP)

21.2 LDAP {#212-ldap}

21.2.1 轻量目录服务 {#2121-轻量目录服务}

  • LDAP(Lightweight Directory Access Protocol)

  • X.500 标准的部分特性集(各厂家不同)

  • 基于 TCP/IP 协议通信(TCP 389)

  • 可构建面向互联网和本地网络的目录服务

  • 最常见的LDAP服务

    • 微软的活动目录 AD
      • 企业网络资源全部加入域,统一存储、统一呈现、统一管理、安全边界
    • Novell eDirectory
  • 命名空间通常与DNS命名保持一致

  • 在目录服务内所有存储对象都有唯一的路径名称

  • 命名空间

    • 全局路径:Distinguished Name(DN)
    • 相对路径:Relative Distinguished Name(RDN)
    • 目录容器:Directory Container(DC)
    • 组织单位:Organisation Unit(OU)
    • 数据项:entries(object、class)
      • 一组预先定义的属性集合
      • uid、姓、名、显示名、账号、邮箱、电话、地址、照片......
    • 基础架构:Schema
    • 通用名:common name(CN)
  • 命名空间命名方式

    • 无固定的命名规则

    • 按照地理空间命名

    • 按照域名的方式,例如:uid=babs,ou=People,dc=ex,dc=com

21.2.2 LDAP协议 {#2122-ldap协议}

  • LDAP 最初作为TCP/IP客户端与 X.500 目录服务网关之间的通信协议
  • LDAPv3
    • 强身份认证和数据加密
    • 基于证书的SSL加密
    • 使用Unicode编码实现国际化
    • Schema 可扩展

21.2.3 使用OpenLDAP {#2123-使用openldap}

  1. 环境准备

    1. 修改主机名,将此LDAP主机名命名为ldap.lab.com(使用域名的方式)
      1. 先修改 /etc/cloud/cloud.cfg ,允许修改主机名,修改配置项 preserve_hostname: true
      2. 修改主机名,将主机名配置到 /etc/hostname 文件中
    2. 在/etc/hosts文件,在其中配置本机主机名与本机IP对应项,实际情况应配置在DNS服务器上
  2. 安装OpenLDAP(Ubuntu Linux 中默认的 LDAP 实现) ,命令:sudo apt install slapd ldap-utils

    • slapd:LDAP的服务器端程序
    • ldap-utils:LDAP工具包,包含对LDAP进行管理的各种工具
      • ldapadd:添加数据
      • ldapdelete:删除数据
      • ldapmodify:修改
      • ldapsearch:查询
      • ldappasswd:修改密码
    • 安装过程中会要求为admin账号设置密码
  3. 初始化配置

    1. 设置LDAP服务器名称,命令:sudo vim /etc/ldap/ldap.conf

      BASE    dc=lab,dc=com	# dc与域名保持一致
      URI     ldap://ldap.lab.com:389		# 通过URI来查询数据,389可以加也可以不加,因为默认使用端口就是389
      
    2. 初始化配置(只需要全新安装之后执行一次就可以),命令:sudo dpkg-reconfigure slapd

    3. 验证

      1. 初始化是否成功,命令:sudo slapcat
      2. 查看文件,命令:sudo tree /etc/ldap/slapd.d/

      3. 查询,命令:ldapsearch -x -LLL -b dc=lab,dc=com dn

      • -x:简单身份验证
      • -LLL:以LDIF文件格式显示结果
      • -b:基地址
  4. 使用

    • 添加数据

      1. 创建并编辑文件添加数据,命令:vim add.ldif

        # 创建一个ou
        dn: ou=People,dc=lab,dc=com
        objectClass: organizationalUnit
        ou: People
        
        # 创建一个ou
        dn: ou=Group,dc=lab,dc=com
        objectClass: organizationalUnit
        ou: Group
        
        # 创建一个组
        dn: cn=developers,ou=Group,dc=lab,dc=com
        objectClass: posixGroup
        cn: developers
        gidNumber:3000
        
        # 创建一个用户账号
        dn: uid=zhangsan,ou=People,dc=lab,dc=com
        # 继承这三个类型,不是随便写的,这三个事先已经在 Schema 定义过了的
        objectClass: inetOrgPerson
        objectClass: posixAccount
        objectClass: shadowAccount
        uid: zhangsan
        sn: zhang
        givenName: san
        cn: san zhang
        displayName: San Zhang
        uidNumber: 2000
        gidNumber: 3000
        userPassword: pass123
        loginShell: /bin/bash
        homeDirectory: /home/zhangsan/
        
      2. 导入数据,命令:ldapadd -x -D cn=admin,dc=lab,dc=com -W -f add.ldif

        • -x:简单身份认证
        • -D:指定管理员
        • -W:提示输入密码
        • -f:指定 ldif 文件

      3. 验证,命令:ldapsearch -x -LLL -b dc=lab,dc=com 'uid=zhangsan' cn sn gidNumber uidNumber givenName

    • 修改数据

      1. 创建并编辑文件添加数据,命令:vim modify.ldif

        dn: uid=zhangsan,ou=People,dc=lab,dc=com	# 修改这个对象
        changetype: modify
        replace: givenName	# 替换giveName这个属性的值
        givenName: Michael	# 值替换为Michael
        -				# 如果替换多个属性,每个属性之间用 - 来进行分隔
        replace: sn
        sn: Jordan
        
      2. 执行修改,命令:ldapmodify -x -D cn=admin,dc=lab,dc=com -W -f modify.ldif

      3. 验证:命令:ldapsearch -x -LLL -b dc=lab,dc=com uid=zhangsan cn sn gidNumber uidNumber givenName

21.2.4 lam安装配置 {#2124-lam安装配置}

  • WEB应用程序 ldap-account-manager(lam)

    • 其他选择 phpLDAPAdmin,安装:sudo apt install phpldapadmin
  • 安装

    1. 安装Apache,命令:sudo apt install apache2

    2. 安装依赖模块,命令:sudo apt install php php-cgi libapache2-mod-php php-common php-pear php-mbstring

    3. 激活依赖模块,命令:sudo a2enconf php7.2-cgi

    4. 重新加载Apache配置,命令:sudo systemctl reload apache2

    5. 重启Apache服务,命令:sudo systemctl restart apache2

    6. 安装lam,命令:sudo apt install ldap-account-manager

    7. 然后打开浏览器访问就可以了,http://ip/lam

  • 初始配置

    1. LAM configuration --> Edit server profiles --> 登录(账号lam默认密码时lam)

      • General settings

      • Account types

    2. 管理页面只允许一些安全的IP来进行访问,命令:sudo vim /etc/apache2/conf-enabled/ldap-account-manager.conf

      <IfModule mod_authz_core.c>
          # Require all granted	# 默认情况下是允许所有的IP来访问
          Require ip 127.0.0.1 192.168.10.0/24 192.168.18.0/24 # 配置成只有这些IP才可以访问
      </IfModule>
      

      • 重启Apache服务,命令:sudo systemctl restart apache2

21.2.5 Win+Linux客户端 {#2125-winlinux客户端}

  • Windows客户端

    • GINA 提供 windows 系统登陆界面

      • 支持本机、域帐号登陆
    • pGina 开源身份认证提供者

      • 集成并替换windows系统默认的GINA
      • 通过插件支持大量身分验证数据存储(LDAP、MySQL、RADIUS)
      • 下载安装稳定版,http://pgina.org/
    • 配置使用

      • 测试成功之后,重启windows就可以使用LDAP进行身份认证了
  • Linux客户端

    1. 域名解析,首先确保Linux客户端可以连接到LDAP服务器上(使用域名或者IP地址)

    2. 安装客户端 ,命令:sudo apt install libnss-ldap libpam-ldap ldap-utils nscd

    3. 配置系统身份认证方式中加入LDAP认证方式,命令:sudo vim /etc/nsswitch.conf

      # 在下面这三个选项最后面添加ldap,如果本机身份认证不通过再试试LDAP身份认证能不能通过
      passwd: compat systemd ldap
      group: compat systemd ldap
      shadow: compat ldap
      

    4. 配置pam做身份认证时会去找LDAP,命令:sudo vim /etc/pam.d/common-password

      • pam时Linux默认的身份认证组件
      # password        [success=1 user_unknown=ignore default=die]     pam_ldap.so use_authtok try_first_pass	# 第26行,删掉其中的 use_authtok
      

    5. 命令:sudo vim /etc/pam.d/common-session

      # 添加下面这行,允许使用LDAP身份认证登录进来的账号创建用户主目录,并将主目录掩码设置为077
      session optional        pam_mkhomedir.so skel=/etc/skel umask=077
      
    6. 重启nscd服务,命令:sudo systemctl restart nscd.service

    7. 验证,命令:getent passwd zhangsan 如果能查到账号信息则客户端配置成功,或者使用su命令将自己切换到zhangsan账号,如果能切换成功也说明LDAP客户端配置成功

    8. 验证成功后重启Linux下次就可以使用LDAP中的账号进行身份认证进行登录了(登录时选择Not listed?)

第 22 章 代理和VPN {#第-22-章-代理和vpn}

22.1 代理与VPN基本概念 {#221-代理与vpn基本概念}

  • 时间、带宽、管控 都影响网络使用体验
  • 作为改善技术,VPN / 代理 可以突破限制改善体验
  • 代理主要提高访问速度;VPN更注重安全性
  • 在某些应用场景中,作用非常相似
  • 作为中间层,双向模拟(翻墙)
  • 网络代理服务
    • 客户端将访问请求发给 Proxy,而非直连目标
    • 代理转发请求给目标,并将结果返回给客户端
  • 正向代理
    • 提高速度、内容控制、安全
  • 反向代理
    • 速度、安全、分发

22.2 squid代理 {#222-squid代理}

22.2.1 安装 {#2221-安装}

  • 命令:sudo apt install squid

22.2.2 配置 {#2222-配置}

  1. 编辑配置文件 ,命令:sudo vim /etc/squid/squid.conf

    # http_port 3128	# 默认侦听在所有网卡的3128端口
    # 如果是给内网的机器做代理就不应该侦听在外网网卡的3128端口上而侦听在内网网卡的3128端口上(假设有好几块网卡)
    http_port 192.168.2.20:3128	# 设置侦听在某一块网卡的3128端口
    
    # 定义日志文件位置
    access_log daemon:/var/log/squid/access.log squid
    
    # 配置缓存
    cache_dir ufs /var/spool/squid3 100 16 256	# 缓存存放目录
    refresh_pattern -i \.(gif|png|jpg|jpeg|ico)$ 3600 90% 86400	# 配置缓存图片文件,86400秒刷新一次
    
    
    # acl访问控制列表,然后通过其他的配置选项来配置acl列表中的资源是否可以访问或者什么时候可以访问等
    # 定义acl,此acl的名称,资源类型,具体的资源
    acl localnet src 192.168.2.0/24	# 192.168.2.0/24这个网段(设置只允许这个网段可以使用本机代理)
    acl SSL_ports port 443			# 端口类型的访问控制列表
    # acl名称可以分多条语句配置比如下面的 Safe_ports
    acl Safe_ports port 80          # http
    acl Safe_ports port 21          # ftp
    acl Safe_ports port 443         # https
    acl Safe_ports port 70          # gopher
    acl Safe_ports port 210         # wais
    acl Safe_ports port 1025-65535  # unregistered ports
    acl Safe_ports port 280         # http-mgmt
    acl Safe_ports port 488         # gss-http
    acl Safe_ports port 591         # filemaker
    acl Safe_ports port 777         # multiling http
    acl CONNECT method CONNECT		# 方法类型的访问控制列表
    
    
    # 访问控制规则
    # 把禁止的放在前面,允许的放在后面,因为是从上往下匹配的,一条匹配中了就不会再往下匹配了
    http_access deny !Safe_ports	# !表示非,拒绝不在Safe_ports列表中的端口进行访问
    http_access deny CONNECT !SSL_ports	# 不在SSL_ports列表中的端口发起CONNECT请求都拒绝
    http_access allow localhost manager	# 允许本机访问缓存服务器
    http_access deny manager			# 静止其他机器访问缓存服务器
    http_access allow localhost			# 运行使用者对本机发起http请求
    http_access deny all		# 除了允许的,其他一切拒绝
    
    # 例如,只允许访问sina.com和163.com这两个域名
    acl localnet src 192.168.2.0/24			# 192.168.2.0/24这个网段
    acl menhu dstdomain .sina.com .163.com	# 定义acl访问控制列表,定义域名资源使用dstdomain,如果有资源中间使用空格来隔开,定义这个acl名称叫做menhu(随意,自己认识就行)
    # 下面这条语句要配置在http_access deny all的前面,因为规则是按先后顺序匹配的,匹配到一条之后就不会再往后匹配了
    http_access allow localnet menhu	# 允许localnet中定义的网段可以访问menhu中定义的域名
    
    # 例如下班时间可以访问,上班时间不可以访问
    
    acl localnet src 192.168.2.0/24
    acl menhu dstdomain .sina.com .163.com
    acl xiaban time MTWHFAS 18:00-23:59		# 定义下班时间,只当规则时根据的是服务器本地时间
    	# M:星期一  T:星期二  W:星期三  H:星期四  F:星期五  A:星期六  S:星期日
    http_access allow localnet menhu xiaban	# 在xiaban的时间段内,允许localnet中定义的网段可以访问menhu中定义的域名
    
    # 例如,对url进行过滤,不允许下载exe文件
    acl localnet src 192.168.2.0/24			# 192.168.2.0/24这个网段
    acl noexes url_regex -i \.exe$	# 使用url正则,-i表示不区分大小写,.exe$表示以exe结尾的
    http_access deny noexes			# 禁止ulr以exe结尾的不给通过
    
  2. 重新加载配置文件,命令:sudo kill -SIGHUP `cat /var/run/squid.pid`

22.3 VPN {#223-vpn}

22.3.1 VPN技术原理 {#2231-vpn技术原理}

  • 企业内部系统不应对外开放
    • 出差在外的企业员工需要访问公司内部系统
    • 分公司、合作商需要安全的访问指定企业内部系统
    • 专线网络费用高昂且不灵活
    • 远程访问安全性欠缺
  • 虚拟专用网(VPN --- Virtual Private Network)
    • 基于并不安全的网络线路,通过加密技术构建安全的信息通道(tunnel)
    • VPN 用户获得如同在内网一样的访问使用体验
  • 与Proxy相比
    • VPN 更加安全、成本高、部署难度大
    • VPN 一旦部署完成后使用简单
    • Proxy 属于一种中间层,VPN 更接近路由(对应用透明,无需设置代理)
    • VPN 更完善的认证、加密、授权控制
  • VPN 类型
    • PPTP
    • L2TP
    • IPSec
    • SSL

22.3.2 OpenVPN简介 {#2232-openvpn简介}

  • 全特性的开源SSL VPN
  • 跨平台 windows、linux、macox、ios、android
  • 通过非受信网络连接上网时保证安全
  • 出差员工访问企业内部系统
  • 伪装为国外地址,规避地理限制和审核(翻墙)
  • 需要(独立的)证书颁发机构CA,完成PKI架构

22.3.3 OpenVPN安装 {#2233-openvpn安装}

  • 准备两台虚拟机,一台做VPN服务器,一台给VPN服务器做证书
  1. 在VPN Server上,安装OpenVPN,命令:sudo apt install openvpn

  2. 在VPN Server和CA Server上,安装EasyRSA,既可以做CA的服务器端,也可以在客户端上安装,然后客户端使用此软件包生成证书的密钥对,生成证书的申请文件发给服务器端来申请证书

    • 第一种方式官方仓库安装(不是最新版),命令:sudo apt install easy-rsa

    • 第二种方式(最新版),证书服务器上执行

      1. 下载最新版,命令:wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.6/EasyRSA-unix-v3.0.6.tgz

      2. 解压,命令:tar zxvf EasyRSA-unix-v3.0.6.tgz

      3. 进入到解压后得到的目录中,命令:cd EasyRSA-v3.0.6/

      4. 复制例子文件,命令:cp vars.example vars

      5. 基于复制得到的例子文件进行修改配置,命令:vim vars

        # 以下项默认是注释的,需要更具实际情况进行修改(发放证书的主体信息)
        set_var EASYRSA_REQ_COUNTRY    "CN"			# 此证书服务器是哪个国家的
        set_var EASYRSA_REQ_PROVINCE   "AnHui"		# 此证书服务器是哪个省的
        set_var EASYRSA_REQ_CITY       "HeFei"		# 此证书服务器是哪个市的
        set_var EASYRSA_REQ_ORG        "LAB"		# 此证书服务器是哪个公司或组织的
        set_var EASYRSA_REQ_EMAIL      "admin@lab.com"	# 此证书服务器联系人邮箱
        set_var EASYRSA_REQ_OU         "IT"			# 此证书服务器是哪个部门
        
      6. 初始化PKI架构,命令:./easyrsa init-pki

      7. 创建证书颁发机构,生成CA服务器自己的公私钥,命令:./easyrsa build-ca nopass

        • nopass:不给私钥加密码,真实情况下不要nopass这一条,给私钥文件加一个密码,增加安全性
        • 生成过程中会要求输入一个Common Name(通用名),默认是CA,一般不需要修改
        • ca.crt:公钥证书,用于验证CA签名的其他证书(C/S都需要)
        • ca.key:CA的私钥,用于签名所有C/S证书(应私密保存)
        • 证书服务器在不使用时,建议关机
    • 第二种方式(最新版),VPN服务器上执行

      1. 下载最新版,命令:wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.6/EasyRSA-unix-v3.0.6.tgz

      2. 解压,命令:tar zxvf EasyRSA-unix-v3.0.6.tgz

      3. 进入到解压后得到的目录中,命令:cd EasyRSA-v3.0.6/

      4. 初始化PKI架构,命令:./easyrsa init-pki

      5. 生成证书申请文件,命令:./easyrsa gen-req vpnserver nopass

        • vpnserver:证书名字
        • nopass:不给私钥加密码,真实情况下不要nopass这一条,给私钥文件加一个密码,增加安全性
        • 生成过程中会要求输入一个Common Name(通用名),这里默认是vpnserver

      6. 把私钥复制到OpenVPN配置目录中去,因为vpn到时候要用这个私钥,命令:sudo cp pki/private/vpnserver.key /etc/openvpn/

      7. 把证书请求文件复制到证书服务器上去,命令:scp pki/reqs/vpnserver.req lw@192.168.2.35:/tmp

      8. 在证书服务器上执行

        1. 导入证书请求文件,命令:./easyrsa import-req /tmp/vpnserver.req vpnserver 导入时还要取一个Common Name,这里叫vpnserver

        2. 生成签名证书,命令:./easyrsa sign-req server vpnserver 签发证书的类型是server,名称叫vpnserver

        3. 将生成的公钥证书复制回VPNServer上,命令:scp pki/issued/vpnserver.crt lw@192.168.2.35:/tmp

        4. 将CA服务器的公钥证书复制到VPNServer上,命令:scp pki/ca.crt lw@192.168.2.35:/tmp 用来解密发放给VPNServer请求的证书(使用CA服务器私钥进行签名)的信息

      9. 将服务器发送过来的两个证书复制到openvpn配置目录下,命令:sudo cp /tmp/vpnserver.crt /tmp/ca.crt /etc/openvpn/

      10. 生成Diffie-Hellman密钥(保证密钥交换时的安全)

        1. 生成HMAC签名(TLS完整性校验),命令:./easyrsa gen-dh
        2. 生成VPN通信过程中要使用的密钥,命令:openvpn --genkey --secret ta.key ta.key也可以叫其他名字,但是如果改了名字的话再vpn配置文件中也需要修改对应的选项,配置文件中默认使用的时ta.key
        3. 将生成的证书和密钥一道openvpn配置目录下,命令:sudo cp ta.key pki/dh.pem /etc/openvpn/
    • 服务端证书设置全部完成

  3. 生成客户端证书

    • 在VPN服务器上生成客户端证书
    • 使用脚本批量自动生成客户端配置文件
    • 生成客户端证书密钥 / 请求文件(VPN Server上执行)
      1. 创建证书文件目录,命令:mkdir -p ~/client-configs/keys
      2. 设置权限,提高安全性,命令:chmod -R 700 ~/client-configs
      3. 进入到,EasyRSA目录下,命令:cd ~/EasyRSA-v3.0.6/
      4. 为client1生成证书,命令:./easyrsa gen-req client1 nopass
      5. 将生成的私钥拷贝到存放私钥的目录中去,命令:cp pki/private/client1.key ~/client-configs/keys/
      6. 将client1证书请求文件复制到CA Server上去,命令:scp pki/reqs/client1.req lw@192.168.2.35:/tmp
      7. 再CA Server上执行
        1. 导入客户端证书请求文件,命令:./easyrsa import-req /tmp/client1.req client1
        2. 签发证书,命令:./easyrsa sign-req client client1
        3. 将签发的证书复制到VPN Server上,命令:scp pki/issued/client1.crt lw@192.168.2.35:/tmp
      8. 将证书复制到统一存放证书的目录中去,命令:cp /tmp/client1.crt ~/client-configs/keys/
      9. 将VPN通信过程中使用的密钥拷贝到统一存放密钥目录中去,命令:cp ta.key ~/client-configs/keys/
      10. 将CA Server的公钥证书拷贝到统一存放客户端证书目录中去,因为客户端需要这个证书来验证VPN Server中CA Server签名的证书是否是合法证书,命令:sudo cp /etc/openvpn/ca.crt ~/client-configs/keys/

22.3.4 OpenVPN配置 {#2234-openvpn配置}

  1. 复制例子配置文件,命令:sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/

  2. 进入到OpenVPN的配置目录下,命令:cd /etc/openvpn/

  3. 解压例子配置文件,命令:sudo gzip -d server.conf.gz 解压会得到server.conf这个文件

  4. 编辑配置文件,命令:sudo vim server.conf

    tls-auth ta.key 0	# VPN通信过程中使用的密钥
    key-direction 0		# 新增配置
    cipher AES-256-CBC	# 对称密钥使用的加密算法
    auth SHA256			# 新增配置,身份认证过程使用的加密算法
    
    dh dh.pem		# 改为你的dh证书的名字
    
    # 删除下面行前面的; 激活这两行配置
    user nobody
    group nogroup
    
    # 强制客户端所有流量路由至 tun0,删除下面行前面的; 激活这两行配置
    # tun0是VPN服务器生成的隧道网卡
    push "redirect-gateway def1 bypass-dhcp"
    push "dhcp-option DNS 8.8.8.8"	# 设置DNS服务器
    push "dhcp-option DNS 8.8.4.4"	# 设置DNS服务器
    
    # 默认使用udp的1194端口
    port 1194
    proto udp
    # 如果要使用TCP的443端口需要这样配置
    port 1194
    proto tcp
    explicit-exit-notify 0	# 新增配置
    
    # 指定服务器证书文件
    ca ca.crt			# CA Server公钥证书
    cert vpnserver.crt	# 向CA Server申请的证书
    key vpnserver.key	# 向CA Server申请的证书对应的密钥
    
  5. 启动服务器路由功能,命令:sudo vim /etc/sysctl.conf

    net.ipv4.ip_forward=1	# 取消注释
    
    • 让配置生效,命令:sudo sysctl -p
  6. 修改防火墙规则实现NAT

    1. 确定默认路由网卡名称,命令:ip route | grep default 得到对应的网卡名称

    2. 编辑防火墙配置文件,命令:sudo vim /etc/ufw/before.rules 直接编辑配置文件添加防火墙规则会优先于使用ufw命令添加的防火墙规则

      # START OPENVPN RULES
      *nat
      :POSTROUTING ACCEPT [0:0]
      # 注意下面这一行中的网卡要配置成自己机器网卡的名字
      -A POSTROUTING -s 10.8.0.0/8 -o enp0s3 -j MASQUERADE	# 把来源10.8.0.0/8(客户端得到的地址)这个网段的地址转换为enp0s3这块网卡绑定的IP地址,10.8.0.0/8由VPN配置文件中配置的,仅用来客户端和VPN服务器来使用
      COMMIT
      # END OPENVPN RULES
      
    3. 开启防火墙转发包,命令:sudo vim /etc/default/ufw

      DEFAULT_FORWARD_POLICY="ACCEPT"		# 默认是DROP,改为ACCEPT
      
    4. 启动防火墙及规则

      1. 命令:sudo ufw allow 1194/udp 开启VPN访问端口
      2. 命令:sudo ufw allow OpenSSH 允许SSH进行远程连接
      3. 命令:sudo ufw enable 开启防火墙,如果之前防火墙就开着在(Ubuntu默认关闭防火墙),需要先关闭再开启
        • sudo ufw disable 关闭防火墙
  7. 启动VPN服务

    1. 启动VPN,命令:sudo systemctl start openvpn@server server是配置文件的名称(/etc/openvpn/server.conf)

    2. 查看运行状态,命令:sudo systemctl status openvpn@server

    3. 设置开机自启,命令:sudo systemctl enable openvpn@server

    4. 查看VPN虚拟网卡,命令:ip addr show tun0

22.3.5 客户端安装配置 {#2235-客户端安装配置}

  • 在VPN Server上为客户端创建配置文件

    1. 创建配置文件模板(VPN Server上执行)

      1. 命令配置文件存放目录,命令:mkdir -p ~/client-configs/files

      2. 复制例子配置文件,命令:cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf

      3. 编辑复制得到的例子配置文件,命令:sudo vim ~/client-configs/base.conf

        # 在最下方添加这三行,仅针对Linux客户端,不是Linux客户端就不用配置,用来更新域名解析相关的配置
        # script-security 2
        # up /etc/openvpn/update-resolv-conf
        # down /etc/openvpn/update-resolv-conf
        
        # 修改下方的配置
        proto udp						# 配置vpn服务器使用什么协议
        remote 192.168.2.35 1194		# 将默认的my-server-1修改为vpn服务器的ip,1194是端口号
        
        # 将前面的;去掉  取消注释
        user nobody		
        group nogroup	# 如果是centos客户端这一行改为group nobody
        
        # 证书相关配置,都注释掉,证书相关信息都会提取出来然后加到配置文件中,不需要单独的证书文件
        # ca ca.crt
        # cert client.crt
        # key client.key
        # tls-auth ta.key 1
        
        cipher AES-256-CBC	# 加密方式需要和服务器保持一致
        auth SHA256			# 新增配置项
        key-direction 1		# 新增配置项
        
    2. 创建脚本文件用来生成配置文件,命令:vim ~/client-configs/make_config.sh 脚本参数为客户端标识名

      #!/bin/bash
      KEY_DIR=~/client-configs/keys		# 存放证书和密钥的目录
      OUTPUT_DIR=~/client-configs/files	# 输出目录
      BASE_CONFIG=~/client-configs/base.conf	# 模板配置文件
      # 配置证书和密钥
      cat ${BASE_CONFIG} \
          <(echo -e '<ca>') \
          ${KEY_DIR}/ca.crt \
          <(echo -e '</ca>\n<cert>') \
          ${KEY_DIR}/${1}.crt \
          <(echo -e '</cert>\n<key>') \
          ${KEY_DIR}/${1}.key \
          <(echo -e '</key>\n<tls-auth>') \
          ${KEY_DIR}/ta.key \
          <(echo -e '</tls-auth>') \
          > ${OUTPUT_DIR}/${1}.ovpn
      
    3. 设置脚本权限,命令:chmod 700 ~/client-configs/make_config.sh

    4. 进入到脚本所在目录中,命令:cd ~/client-configs

    5. 执行脚本创建一个客户端配置文件,命令:sudo ./make_config.sh client1

  • Ubuntu连接OpenVPN Server

    1. 首先从VPN Server上获取客户端配置文件,例如命令:scp lw@192.168.2.35:~/client-configs/files/client1.ovpn .

      # 因为是Linux客户端,所以下面这三行要取消注释
      script-security 2
      up /etc/openvpn/update-resolv-conf
      down /etc/openvpn/update-resolv-conf
      
    2. 安装OpenVPN,命令:sudo apt install openvpn

    3. 连接VPN服务器

      • 第一种方式,命令行方式,命令:sudo openvpn --config client1.ovpn > /dev/null 2>&1 & 让命令在后台自动运行

      • 第二种方式,gnome桌面环境,图形化方式连接

        1. 安装gnome桌面OpenVPN相关组件,命令:sudo apt install network-manager-openvpn network-manager-openvpn-gnome

          • 其他VPN客户端组件

            | 服务器 | 客户端组件 | |---------------------------------|-----------------------------| | Cisco Concentrator | network-manager-vpnc | | Cisco OpenConnect | network-manager-openconnect | | PPTP(Microsoft VPN) | network-manager-pptp | | strongSwan(for some IPsec VPNs) | network-manager-strongswan |

        2. 在 设置 --> 网络 --> VPN --> 右上角加号 --> 从文件导入 ---> 选择VPN客户端配置文件 ---> 添加

  • WIndows连接OpenVPN Server

    1. 下载连接软件,https://openvpn.net/index.php/open-source/downloads.html
    2. 搞到VPN客户端配置文件,例如C:\Program Files\OpenVPN\config\client2.ovpn
    3. 以管理员身份运行客户端程序
  • IOS连接OpenVPN Server

    • App Store 搜索 OpenVPN Connent

  • Android连接OpenVPN Server

    • OpenVPN Connect软件

  • MacOS连接OpenVPN Server

    1. 下载客户端软件,https://tunnelblick.net/downloads.html
    2. 安装结束自动提示导入客户端配置文件

22.3.6 撤销客户端证书 {#2236-撤销客户端证书}

  1. CA Server上执行

    1. 进入到EasyRSA目录,命令:cd EasyRSA-3.0.4/
    2. 吊销证书,命令:./easyrsa revoke client1
    3. 生成证书吊销列表,命令:**./easyrsa gen-crl ** 生成crl.pem证书吊销列表证书
    4. 发证书吊销列表发送到所有使用本证书服务器的应用服务器上去,命令:scp /pki/crl.pem lw@192.168.2.35:/tmp
  2. VPN Server上执行

    1. 将证书吊销列表复制到OpenVPN配置目录下,命令:sudo cp /tmp/crl.pem /etc/openvpn

    2. 编辑OpenVPN配置文件,命令:sudo vim /etc/openvpn/server.conf

      # 增加证书吊销指令配置
      crl-verify crl.pem
      
    3. 重启OpenVPN服务,命令:sudo systemctl restart openvpn@server

第 23 章 安全设置 {#第-23-章-安全设置}

23.1 安全基础认识 {#231-安全基础认识}

23.1.1 概述 {#2311-概述}

  • 什么是安全?如何才能保证安全?
    • 安全的范围太广,做到绝对安全是不可能的
    • Linux 默认安装已经很安全,当更多的了解安全仍非常必要
    • 打造一个相当安全的系统(增加入侵者的成本)
  • 内部 / 外部威胁
    • 90%的安全事件来自于内部员工和已经离职的员工
    • 外部威胁是我们经常谈论,并且感觉距离遥远的事情
  • 黑客 / 骇客 的古典定义
    • Hacker 是正面的技术高手,勇于创新探索解决问题
    • Cracker 利用技术干坏事,以破坏恐怖谋取利益为目标
    • 现在公共话语中并不刻意区分这两种称呼
    • 如果想与他人讨论,请提前明确自己的定义(黑/白)

23.1.2 现状与防护思路 {#2312-现状与防护思路}

  • 现状
    • 自动化工具、漏洞利用代码丰富(大部分攻击都源自自动化工具)
    • 学习成本低,黑白难辨(同时都是)
    • 系统防护困难(攻防成本对比严重失调)
  • 防护思路
    • 风险评估:攻击面
    • 制定策略:最小化、明确需求
    • 安全管理:安全是管理
    • 应急预案:突发事件
    • 威胁情报:了解安全行业
  • 常见错误理解
    • 安全是安全从业者的事情
    • 为了安装简单,装所有的包,开所有的服务(版本号、banner信息)
    • 有了边界防火墙则不需要主机防火墙
    • 随意开放各种访问方式(后门)
    • 公司内部网络是安全的

23.2 账号安全 {#232-账号安全}

23.2.1 概述 {#2321-概述}

  • 用户管理是系统安全最重要的方面
    • 密码策略
    • 权限控制

23.2.2 账号设置 {#2322-账号设置}

  • Ubuntu 默认禁用root账号

    • 默认使用不匹配任何加密值的密码,所有无法直接登陆(sudo)
    • 设置密码即可启用 root 登陆
    • 安装过程创建的账号默认属于 sudo 组
    • 设置root密码,命令:sudo passwd
    • 禁用root账号密码(解锁 -u ),命令:sudo passwd -l root
  • 增加管理员账号

    • 将luo账号加入到sudo组,命令:sudo usermod -aG sudo luo
    • 将luo账号加入到sudo组,sudo visudo 然后进行配置(本质是编辑 /etc/sudoers文件 )
    • 切换到root账号,命令:sudo su
    • 尽量减少管理员账号
  • 多用户环境下,用户主目录默认权限是全局可读,修改只有属主和数组对其有权限

    • 查看用户主目录权限,命令:ls -ld /home/username

    • 修改用户主目录权限(主目录下的文件和子目录不建议更改),命令:sudo chmod 0750 /home/username

    • 添加用户时就自动设置用户主目录的权限,命令:sudo vim /etc/adduser.conf

      # 修改此配置选项
      DIR_MODE=0750	# 用户主目录的默认权限
      
    • 添加新用户账号,命令:sudo adduser username

23.2.3 密码设置 {#2323-密码设置}

  • 密码复杂度

    • 使用sudo设置密码时不受密码规则限制

    • 设置密码复杂度,命令:sudo vim /etc/pam.d/common-password

      # minlen=8 密码最小长度为8
      # lcredit=1 最少要有1个小写字母
      # ucredit=1 最少要有一个大写字母
      # dcredit=2 最少要有两个数字
      # ocredit=1 最少要有一个特殊字符
      password	[success=1 default=ignore]	pam_unix.so obscure sha512 minlen=8 lcredit=1 ucredit=1 dcredit=2 ocredit=1
      
  • 密码过期

    • 查看用户账号信息,命令:sudo chage -l username (参数是小写的L)
    • 命令:sudo chage -E 01/31/2020 -m 5 -M 90 -I 30 -W 14 username
      • -E:过期日期
      • -m:密码可以更改的最小天数,为零代表任何时候都可以更改密码
      • -M:密码保持有效的最大天数
      • -I(大写的i):密码过期后多少天仍可以改密码,过期锁定账号
      • -W:过期前多少天警告
    • 以向导方式进行设置,命令:sudo chage username

23.2.4 SSH设置 {#2324-ssh设置}

  • 应用和服务使用其他身份认证机制,需要单独配置账号安全

  • 锁定账号无法阻止使用公钥认证的SSH远程用户

    • ~/.ssh/authorized_keys
    • 需要删除主目录下的 .ssh 目录
  • 禁用账号不会强制断开已经建立的SSH连接

    • 查看已经登陆终端的账号,命令:who
      • 命令:who | grep username
    • 强制踢掉已登录账号,命令:sudo pkill -f pts/0 pts/0数字由who命令查询得到
  • 指定可SSH远程登陆的用户(重启服务生效)

    1. 添加组,命令:sudo addgroup sshlogin

    2. 编辑配置文件只允许属于sshlogin组的账号进行SSH连接登录,命令:sudo vi /etc/ssh/sshd_config

      AllowGroups sshlogin	# 只允许sshlogin这个组中的账号进行SSH连接登录
      

23.3 控制台安全 {#233-控制台安全}

  • (控制台重启系统快捷键)
    • 禁用 Ctrl+Alt+Delete,命令:sudo systemctl mask ctrl-alt-del.target
    • 重新加载配置,命令:sudo systemctl daemon-reload

23.4 系统信息 {#234-系统信息}

  • 当前登陆账号
    • 显示目前登入系统的用户信息,命令:w
      • 用户 终端 来源 登陆时间 发呆时间 xxxx xxxx 当前运行程序
  • 历史登陆记录
    • 命令:last -d
  • Linux 中一切都是文件,运行中的文件称为进程
  • 目录中被打开的文件
    • 查看/home/lw目录下打开的文件(进程),命令:sudo lsof +D /home/lw
  • 用户打开的所有文件
    • 查看luo账号都运行了哪些文件,命令:sudo lsof -u luo
    • 查看除了luo账号之前的所有其他的账号(包含root)都运行了哪些文件,命令:sudo lsof -u ^luo
  • 结束指定用户的所有进程
    • 命令:sudo kill -9 `lsof -t -u yuanfh`
  • 列出所有的网络连接
    • 命令:sudo lsof -i
  • suid / sgid 的安全隐患
    • 查找启用suid文件,命令:sudo find / -type f -perm -u=s -ls
    • 查找启用sgid文件,命令:sudo find / -type f -perm -g=s -ls
    • 查找没有属主,属组的文件,命令:find / -xdev \( -nouser -o -nogroup \) -print
    • 检查其他人可写、sgid激活、无属主文件

23.5 文件加密 {#235-文件加密}

23.5.1 概述 {#2351-概述}

  • 网络本身不加密
    • 通过不受信网络连接上网
    • 加密信息传输通道是首选方案(VPN)
    • 传输单个文件可使用文件级加密
  • 很多应用也不加密
    • 传输机密信息使用 SSH、SCP

23.5.2 GnuPG {#2352-gnupg}

  • GnuPG

    • Linux 默认安装

    • 工作过程,文件发送者需要用接收者发过来的公钥对文件进行加密,接收者再用对应的私钥对接收到的加密文件进行解密

  • 生成密钥对

    • 命令:gpg --gen-key 通过手机系统的随机信息来生成密钥对,需要输入真名,邮件地址和私钥的保护密码
    • 如果生成密钥对要求有足够的熵,那么打开另一个终端执行下面这条命令
      • 生成随机操作 ,命令:sudo find / -type f | xargs grep somerandomstring > /dev/null

  • 导出公钥文件

    • 命令:gpg --export username > mygpg.pub 导出username密钥对的公钥导出为mygpg.pub文件,username是生成密钥对是要你输入的Real Name,mygpg.pub是公钥文件的名称(随意)
  • 导入公钥文件

    • 命令:gpg --import mygpg.pub 导入对方发送过来的公钥,这样才能使用对方的公钥进行加密,然后对方再用私钥解密
  • 加密文件

    • 命令:gpg --encrypt --recipient luo secret.txt luo:加密使用的公钥,secret.txt:要加密的文件,加密完成后将加密后得到的文件发送给对方,然后对方再用对应的私钥进行解密即可
  • 解密文件

    • 命令:gpg --output secret.txt --decrypt secret.gpg secret.txt:解密得到的文件名(随意),secret.gpg:要解密的文件
  • 查看key列表

    • 命令:gpg --list-keys
  • 删除公钥

    • 命令:gpg --delete-keys luo 删除luo公钥,删除公钥前需要删除对应的私钥
  • 删除私钥

    • 命令:gpg --delete-secret-keys luo 删除luo私钥
  • 通过密钥服务器交换密钥

    • 发送公钥,命令:gpg --keyserver certserver.pgp.com --send-key 0x4C46B027

      • certserver.pgp.com:密钥服务器
      • 4C46B027:公钥ID的后8位

    • 接收公钥,命令:gpg --keyserver certserver.pgp.com --recv-key 0x4C46B027

    • 国内网络受限

23.6 防火墙 {#236-防火墙}

23.6.1 简介 {#2361-简介}

  • 防火墙
    • 访问控制设备
  • Linux 内核包含Netfilter子系统
    • 用于操纵经过服务器的流量
    • 实现包过滤
    • 用户空间管理工具 iptables
  • Ubuntu 默认的防火墙管理工具 UFW
    • 操作简单,默认禁用
    • 功能不全面
    • 主要用作主机防火墙

23.6.2 UFW使用 {#2362-ufw使用}

  • 启用 / 禁用 防火墙

    • 启用防火墙,命令:sudo ufw enable
    • 禁用防火墙,命令:sudo ufw disable
  • 查看状态

    • 查看状态和规则,命令:sudo ufw status
    • 查看状态(详细信息),命令:sudo ufw status verbose
    • 查看状态和规则,显示规则的序号(执行的顺序),命令:sudo ufw status numbered
  • 默认规则

    • 命令:sudo ufw default allow|deny|reject DIRECTION(incoming/outgoing/routed)
  • 增加规则

    • 允许所有IP访问TCP和UDP 22端口,命令:sudo ufw allow 22 不指定协议类型时默认是TCP和UDP
    • 允许所有IP访问TCP 22端口,命令:sudo ufw allow 22/tcp
    • 禁止所有IP访问TCP和UDP 22端口,命令:**sudo ufw deny 22 ** 不指定协议类型时默认是TCP和UDP
  • 增加规则(方向)

    • 允许http入站请求(不加方向默认是入站),命令:sudo ufw allow http
    • 允许http入站请求,命令:sudo ufw allow in http
    • 禁止smtp出站请求,命令:sudo ufw reject out smtp
  • 对规则进行描述

    • 增加规则同时添加对规则的描述,命令:sudo ufw reject telnet comment 'telnet is unencrypted'
  • 插入规则

    • 增加规则并将此规则插入为第二条规则(执行顺序),命令:sudo ufw insert 2 allow 80
  • 增加定向规则

    • from:来源IP
    • to:本机IP(多块网卡)
    • proto:使用的协议
      • 协议:tcp、udp、ah、esp、gre、ipv6、igmp等
    • port:端口
    • 定向规则
      • 拒绝10.0.0.135这个IP使用TCP协议访问本机所有IP(多块网卡)的22端口,并将此规则插入到第三条的规则的位置,命令:sudo ufw insert 3 deny to any port 22 from 10.0.0.135 proto tcp
      • 允许192.168.0.2这个IP使用TCP协议访问本机所有IP(多块网卡)的22端口,命令:sudo ufw allow proto tcp from 192.168.0.2 to any port 22
      • 允许192.168.0.0/24这个网段中所有IP使用TCP协议访问本机所有IP(多块网卡)的22端口,命令:sudo ufw allow proto tcp from 192.168.0.0/24 to any port 22
      • 拒绝10.0.0.0/8这个网段中所有IP使用TCP协议访问本机的192.168.0.1这个IP的25端口,命令:sudo ufw deny proto tcp from 10.0.0.0/8 to 192.168.0.1 port 25
      • 拒绝2001:db8::/32这个IPV6网段中所有IP使用TCP协议访问本机所有IP(多块网卡)的25端口,命令:sudo ufw deny proto tcp from 2001:db8::/32 to any port 25
    • 指定网卡和其他协议
      • on:指定网卡
      • 拒绝eth0网卡入站的流量使用igmp协议访问224.0.0.1这个组播地址,命令:sudo ufw deny in on eth0 to 224.0.0.1 proto igmp
      • 允许eth0网卡入站流量使用gre协议访问eth0网卡上绑定的192.168.0.1这个IP,命令:sudo ufw allow in on eth0 to 192.168.0.1 proto gre
      • 允许任何IP使用TCP协议访问本机所有IP(多块网卡)的80,443,8080到8090端口,此规则描述为web,命令:sudo ufw allow proto tcp from any to any port 80,443,8080:8090 comment 'web'
      • 允许eth0网卡入站流量使用TCP协议访问eth0网卡上绑定的所有IP的80端口,命令:sudo ufw allow in on eth0 to any port 80 proto tcp
  • 增加路由规则

    • 需要首先设置IP转发

      1. 开启路由功能,命令:sudo vim /etc/ufw/sysctl.conf

        # 打开IPV4路由功能
        net/ipv4/ip_forward=1
        
        # 打开IPV6路由功能,不用V6可以不加
        net/ipv6/conf/default/forwarding=1
        net/ipv6/conf/all/forwarding=1
        
      2. 使配置生效,命令:sudo sysctl -p

      3. 禁用防火墙,命令:sudo ufw enable

      4. 启用防火墙,命令:sudo ufw disable

    • 允许eth1网卡进来的流量从eth2网卡出去,命令:sudo ufw route allow in on eth1 out on eth2

    • 允许从eth0网卡进来的流量使用TCP协议访问12.34.56.78这个IP的80端口从eth1网卡出去,命令:sudo ufw route allow in on eth0 out on eth1 to 12.34.56.78 port 80 proto tcp

  • 定义应用程序

    • 为开放端口的服务程序定义程序配置文件 /etc/ufw/applications.d/

    • 适用于为某一个应用程序添加防火墙规则,这个程序使用非标准端口,使用多个端口

    • 添加一个应用程序定义文件,命令:sudo ufw app info CUPS

      [<name>]		# 名称,给ufw使用的名称
      title=<title>	# 标题
      description=<description>	# 描述
      ports=12/udp|34|56,78:90/tcp	# udp的12端口,udp+tcp的34和56端口,tcp的78到90端口
      
    • 允许任何IP访问CPUS中指定的端口,命令:sudo ufw allow app CUPS

    • 更新应用程序定义文件,命令:sudo ufw app update <name>

  • 完整语法规则

    • sudo ufw route allow/reject/deny/limit/ insert/delete/pretend in on eth0 out on eth1 from 1.1.1.1 port 1:65535 to 2.2.2.2 port 22 proto tcp/udp/igmp/esp/ah
  • 限制连接频率

    • 30秒内超过6次连接ssh就拒绝,命令:sudo ufw limit ssh/tcp
  • 启用 / 不启用 IPV6 规则

    • 编辑配置文件,命令:sudo vim /etc/default/ufw

      IPV6=yes	# 启用IPV6规则,改为no则不启用IPV6规则
      
  • 改变名称对应的端口号

    • 编辑配置文件,命令:sudo vim /etc/services

  • 删除规则

    • 加的时候怎么加的,删的时候在前面加delete,命令:sudo ufw delete deny 22
    • 通过序号删除,命令:sudo ufw delete 3
  • 日志

    • UFW 默认不记录日志
    • 识别攻击、规则排错、诊断问题
    • 开启/ 关闭日志
      • 全局开启日志,命令:sudo ufw logging on
        • 设置日志等级,命令:sudo ufw logging low
          • LEVEL:low / medium / high / full
      • 关闭日志,命令:sudo ufw logging off
    • 日志默认存储位置:/var/log/ufw.log
    • 针对某个规则记录日志,命令:ufw allow log 22/tcp
  • 恢复默认

    • 重置规则,命令:sudo ufw reset
  • Shorewall 适合任何网络的高级防火墙

23.6.3 UFW网络防火墙 {#2363-ufw网络防火墙}

  1. 开启IP转发功能,命令:sudo vim /etc/ufw/sysctl.conf

    # 打开IPV4路由功能,取消注释
    net/ipv4/ip_forward=1
    
    # 打开IPV6路由功能,不用IPV6可以不加,取消注释
    net/ipv6/conf/default/forwarding=1
    net/ipv6/conf/all/forwarding=1
    
  2. 允许转发流量,命令:sudo vim etc/default/ufw

    DEFAULT_FORWARD_POLICY="ACCEPT"	# 改为ACCEPT,接收转发流量
    
  3. IP遮盖,命令:sudo vim /etc/ufw/before.rules

    *nat	# NAT地址转换
    :POSTROUTING ACCEPT [0:0]	# 接受路由转发功能
    -A POSTROUTING -s 10.8.0.0/8 -o enp0s3 -j MASQUERADE	# 来源是10.8.0.0/8段的数据包进行NAT地址转换,转换成本机enp0s3网卡的IP地址再发出去
    COMMIT
    
  4. 使配置生效,命令:sudo sysctl -p

  5. 禁用防火墙,命令:sudo ufw enable

  6. 启用防火墙,命令:sudo ufw disable

23.7 AppArmor {#237-apparmor}

23.7.1 简介 {#2371-简介}

  • AppArmor 是一个 Linux 内核安全模块
    • 使不安全和不受信进程在受限的约束下运行
    • 保证进程访问共享文件、行使特权、与其他进程通信
  • 全局强制访问控制机制(MAC)
    • 基于 LSM 的额外安全功能
    • 系统调用前,内核查询AppArmor策略,确定程序是否有权执行操作
    • 不同于SELinux,与用户无关,可用于限制超级用户权限(所有用户继承)
    • 将进程限制在有限的系统资源之上
    • 预设的控制机制,一定程度可预防未知安全漏洞(0day)
  • Ubuntu 默认的安全系统
    • 默认已安装并加载
  • 控制策略
    • 基于安装路径识别程序并控制
    • 策略保存于相应配置文件(profile)中
    • 结合高级静态分析和基于学习的工具实施控制
    • 默认安装包含部分配置文件 /etc/apparmor.d/
    • 部分安装包自带配置文件

23.7.2 安装使用 {#2372-安装使用}

  • 安装额外配置文件 ,命令:sudo apt install apparmor-profiles apparmor-profiles-extra
    • apparmor-profiles:由上游社区管理维护的配置文件
    • apparmor-profiles-extra:由ubuntu、Debian 开发的配置文件
  • 安装用户端管理工具 ,命令:sudo apt install apparmor-utils
  • 控制模式
    • enforcing:强制策略实施并记录被禁请求
    • complaining:只记录被禁请求,但不强制实施禁止
  • 切换模式
    • 切换为强制模式,命令:aa-enforce <配置文件路径>
    • 切换为兼容模式,命令:aa-complain <配置文件路径>
    • 禁用指定 profile,命令:aa-disable <配置文件路径>
    • 审计模式,enforce + 记录成功访问,命令:aa-audit <配置文件路径>
  • 查看状态 ,命令:sudo aa-status
  • 查看当前加载的配置文件 ,命令:sudo cat /sys/kernel/security/apparmor/profiles
  • 配置文件命名规则
    • 与可执行程序绝对路径相同,/ -> .
    • 软连接将最终解析到目标程序
  • 重新加载配置文件
    • 重新加载某一个配置文件,命令:sudo apparmor_parser -r usr.sbin.smbd
    • 重新加载全部配置文件,命令:sudo systemctl reload apparmor.service
  • 更改配置文件
    • 官方仓库中有的配置文件中给应用程序所需要的权限或资源少了(例如smbd),导致了不能启动服务
    • 先启动或重启服务,然后查看系统日志,tail /var/log/syslog,寻找其中包含**apparmor="DENIED"**的行,然后查看所需要的权限或资源
    • 确定了所需要的权限或资源之后编辑服务对应的apparmor配置文件(例如 /etc/apparmor.d/usr.sbin.smbd),在配置文件中增加对应的权限和资源
      • 权限
        • r (读)、w (写)、x (执行)、l (链接)、u(不受限)
  • 从头开始创建新的配置文件
    • 运行程序,并通过 apparmor 监视其系统调用和访问的资源
    • 最需要约束的程序是面向网络的程序(容易遭受黑客攻击)
    • 没有关联配置文件,哪些配置文件公开了一个打开的网络套接字
    • 显示未加载配置文件没有apparmor对其进行保护但侦听网络连接的进程(tcp/udp),命令:sudo aa-unconfined
    • 显示所有关联网络端口的进程,命令:aa-unconfined --paranoid
    • 对mtr创建一个配置文件,命令:sudo aa-genprof mtr
      1. 然后在另外一个终端正常使用mtr,aa-genprof会记录mtr所有对系统的资源请求并记录下来
      2. 然后根据aa-genprof向导生成对应配置文件
    • 切换为强制模式,命令:aa-enforce usr.bin.mtr
    • 重新加载mtr配置文件,命令:sudo apparmor_parser -r usr.bin.mtr
    • 自动检查日志查找程序所需的权限并更新配置文件,命令:sudo aa-logprof
    • 如果是一个很大的程序,建议先让程序运行在兼容模式下,让apparmor收集到应用程序全部的权限再生成对应配置文件,再置为强制模式

23.8 防病毒 {#238-防病毒}

23.8.1 介绍 {#2381-介绍}

  • 恶意软件
    • 病毒、木马、蠕虫、远控、僵尸、勒索、挖矿、流氓、漏洞利用......
  • 通常防病毒和Linux不会出现在同一句话里,BUT!
    • 专门针对Linux发行版的恶意程序
    • 没有 100% 有效的杀毒软件(病毒库互补)

23.8.2 ClamAV {#2382-clamav}

  • 安装

    • 命令:sudo apt install clamav clamav-daemon
      • clamav:安装后每次需要手动运行进行检查
      • clamav-daemon:后台进程,安装后可以配置成时时的进行检查,或者其他程序调用这个后台程序进行查杀
    • 命令:sudo apt install libclamunrar7 让clamav可以查杀压缩包文件
    • 图形化前端(不常用),命令:sudo apt install clamtk
  • 病毒库更新

    • 关闭自动更新进程(等着它自己更新),sudo systemctl stop clamav-freshclam

    • 手动更新病毒库,命令:sudo freshclam

    • 查看更新病毒库日志,命令:less /var/log/clamav/freshclam.log

    • 使用代理进行更新(假如IP被屏蔽了)

      • 修改配置文件,命令:sudo vim /etc/clamav/freshclam.conf

        # 添加以下配置
        HTTPProxyServer 192.168.2.1	# 设置代理服务器IP
        HTTPProxyPort 8080	# 设置代理服务器端口
        
  • 手动扫描

    • 命令:sudo clamscan --max-filesize=3999M --max-scansize=3999M --exclude-dir=/sys/ -i -r / * 这条命令只扫描报告不对病毒进行处理
      • --max-filesize=3999M:最大只扫描3999M文件,超过这个大小的文件就不进行检查
      • --max-scansize=3999M:最多扫描的大小,假设有8000M大小的文件,如果扫描了3999M还没发现病毒那么就不再扫描此文件
      • --exclude-dir=/sys/*:排除此目录,不进行扫描
      • -i:统计显示被病毒感染的文件
      • -r:目录递归扫描
      • /:扫描更目录
      • --remove:如果查到病毒就删掉
      • --bell:如果查到病毒就发出声音经过
      • --move=/tmp/VIRUS:如果查到病毒就移到这个目录中
      • --copy=/tmp/VIRUS:如果查到病毒就复制到这个目录中
  • 测试

  • 扫描调度

    • 命令:at 1:00 tomorrow 明天凌晨1点自动要做的事情,进入到at命令行下

      at> freshclam	# 先更新病毒库
      at> clamscan -i /home/lw	# 再扫描病毒
      at> <EOT>	# 标识任务已经结束了 
      at> 快捷键:CTRL+ D 退出at命令行
      

第 24 章 云计算 {#第-24-章-云计算}

24.1 云计算简介 {#241-云计算简介}

  • 云计算是将资源打碎、分配、发布、交付的一组工具合集
    • 目标是方便快捷的资源交付
    • 计算、存储、网络
  • 美国国家标准与技术学会(NIST)的定义
    • 云计算是一种模型。它通过网络提供可广泛访问的、方便的、可按需调整的公共计算资源集(如网络、服务器、数据存储、应用程序和服务)的访问。这些资源可以立即分配和释放,从而仅需要客户花费最少的精力进行管理和服务提供者的交互。
  • 云计算最早源于亚马逊 AWS
    • 计算资源过剩
    • 资源管理方法成熟
    • 市场的需求
  • 在催生了一个产业之后,各家公司纷纷效仿亚马逊开始自己的云服务
  • 开源的云平台------Openstack
    • 云操作系统,云平台管理项目
    • 管理资源池(计算、网络、存储),目标是简化管理资源分配
    • 云基础设置开发项目,而非独立的产品
    • 基于Apache2.0协议许可发布
    • 可认为是开源 AWS(API / 模板 通用)

未完待续。。。

参考资源 {#参考资源}

赞(5)
未经允许不得转载:工具盒子 » Ubuntu Server 从入门到精通