分类 技术 下的文章

nmcli 命令赋予你直接在 Linux 命令行操作 NetworkManager 工具的能力。

nmcli 命令赋予你直接在 Linux 命令行操作 NetworkManager 工具的能力。它是 NetworkManager 软件包集成的一部分,通过使用一些 应用程序接口(API)来获取 NetworkManager 的功能。

nmcli 发布于 2010 年,用以替代其他配置网络接口和连接的方法,例如 ifconfig。因为它是一个 命令行界面(CLI)工具,被设计用在终端窗口和脚本中,所以对于那些工作在没有 图形用户界面(GUI)的系统的管理员来说,它是一个非常理想的工具。

ncmli 的语法

nmcli 命令可以使用选项来更改它的行为,使用子命令来告诉 nmcli 想使用它的那部分功能,使用操作来告诉 nmcli 你想执行什么操作。

$ nmcli <选项> <子命令> <操作>

nmcli 一共有 8 个子命令,每个子命令有一些相关的网络操作:

  • help 提供有关 nmcli 命令和使用方法的帮助信息
  • general 返回 NetworkManager 的状态和总体配置信息
  • networking 提供命令来查询某个网络连接的状态和启动、禁用连接的功能
  • radio 提供命令来查询某个 WiFi 网络连接的状态和启动、禁用连接的功能
  • monitor 提供命令来监控 NetworkManager 的活动并观察网络连接的状态改变
  • connection 提供命令来启用或禁用网络接口、添加新的连接、删除已有连接等功能
  • device 主要被用于更改与某个设备(例如接口名称)相关联的连接参数或者使用一个已有的连接来连接设备
  • secret 注册 nmcli 来作为一个 NetworkManager 的秘密代理,用以监听秘密信息。这个子命令很少会被用到,因为当连接到网络时,nmcli 会自动做这些事

简单的示例

首先,我们验证一下 NetworkManager 正在运行并且 nmcli 可以与之通信:

$ nmcli general
STATE      CONNECTIVITY  WIFI-HW  WIFI     WWAN-HW  WWAN    
connected  full          enabled  enabled  enabled  enabled

探测总是管理一个系统的首要部分。为了列出内存或磁盘上的网络连接配置,可以使用下面的命令:

$ nmcli connection show
NAME                UUID                                  TYPE      DEVICE
Wired connection 1  ac3241e4-b424-35d6-aaa7-07498561688d  ethernet  enp0s3
Wired connection 2  2279d917-fa02-390c-8603-3083ec5a1d3e  ethernet  enp0s8
Wired connection 3  52d89737-de92-35ec-b082-8cf2e5ac36e6  ethernet  enp0s9

上面的命令使用了 connection 子命令中的 show 操作。

用来运行上面这个例子的测试机器上运行着 Ubuntu 20.04,它安装了 3 个网络适配器:enp0s3enp0s8enp0s9

连接管理

理解 nmcli 的术语是非常重要的。一个网络 连接 connection 包含了一个连接的所有信息。你可以将它看作一个网络 配置 configuration 。“连接”包含了与其相关的所有信息,包括 数据链路层IP 地址信息 。它们是 OSI 网络模型 中的第 2 和第 3 层。

当你在 Linux 上配置网络时,通常来说你是在为某个网络设备(它们是安装在一个电脑中的网络接口)配置连接。当一个连接被某个设备所使用,那么就可以说这个连接被 激活 active 或者 上线 up 了,反之是 停用 inactive 下线 down

添加网络连接

nmcli 允许你快速地创建网络连接并同时为该连接指定参数。为了通过使用“有线连接 2” enp0s8 来创建一个新的连接,你可以利用 sudo 来运行下面的命令:

$ sudo nmcli connection add type ethernet ifname enp0s8
Connection 'ethernet-enp0s8' (09d26960-25a0-440f-8b20-c684d7adc2f5) successfully added.

其中 type 选项指定需要一个 Ethernet 类型的连接,而 ifname(接口名)选项指定你想要为这个连接使用的网络接口设备。

让我们看看发生了什么变化:

$ nmcli connection show
NAME                UUID                                  TYPE      DEVICE
Wired connection 1  ac3241e4-b424-35d6-aaa7-07498561688d  ethernet  enp0s3
Wired connection 2  2279d917-fa02-390c-8603-3083ec5a1d3e  ethernet  enp0s8
Wired connection 3  52d89737-de92-35ec-b082-8cf2e5ac36e6  ethernet  enp0s9
ethernet-enp0s8     09d26960-25a0-440f-8b20-c684d7adc2f5  ethernet  --  

通过上图可以看到新的连接 ethernet-enp0s8 已经创建好了。它的 通用唯一标识符 Universally Unique IDentifier (UUID)也一同被赋予,并且其连接类型为 “Ethernet”。我们可以使用 up 子命令再加上连接名称(或 UUID)来使得这个连接被激活:

$ nmcli connection up ethernet-enp0s8
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/4)

再次查看激活的连接:

$ nmcli connection show --active
NAME                UUID                                  TYPE      DEVICE
Wired connection 1  ac3241e4-b424-35d6-aaa7-07498561688d  ethernet  enp0s3
ethernet-enp0s8     09d26960-25a0-440f-8b20-c684d7adc2f5  ethernet  enp0s8
Wired connection 3  52d89737-de92-35ec-b082-8cf2e5ac36e6  ethernet  enp0s9

可以看到新的连接 ethernet-enp0s8 现在已经被激活了,并且与 enp0s8 网络接口设备绑定。

调整连接

nmcli 命令使得调整现有连接的参数变得更加容易。也许你想将某个网络接口从 动态主机配置协议 Dynamic Host Configuration Protocol (DHCP)改为静态 IP 地址。

假设你需要为你的新连接分配一个固定的 IP 地址 192.168.4.26,那么你需要使用两个命令,一个用于设定 IP 地址,另一个用来将获取 IP 地址的方法改为 manual(手动):

$ nmcli connection modify ethernet-enp0s8 ipv4.address 192.168.4.26/24
$ nmcli connection modify ethernet-enp0s8 ipv4.method manual

记得指定 子网掩码,在我们这个测试的连接中,它是 无类域间路由 Classless Inter-Domain Routing (CIDR)中的 255.255.255.0/24

为了使得你的更改生效,你需要通过停止再重新启用该连接。下面的第一个命令是停用该连接,第二个命令则是启用它:

$ nmcli connection down ethernet-enp0s8
Connection 'ethernet-enp0s8' successfully deactivated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/4)
$ nmcli connection up ethernet-enp0s8
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/6)

假如你想将连接设置为使用 DHCP,则需要将上面的 manual 改为 auto(自动):

$ nmcli connection modify ethernet-enp0s8 ipv4.method auto

设备管理

nmcli 命令中的 device 子命令允许你管理安装在你电脑中的网络接口。

检查设备状态

可以使用下面的命令来快速检查所有网络接口的状态:

$ nmcli device status
DEVICE  TYPE      STATE      CONNECTION        
enp0s3  ethernet  connected  Wired connection 1
enp0s8  ethernet  connected  ethernet-enp0s8    
enp0s9  ethernet  connected  Wired connection 3
lo      loopback  unmanaged  --  

显示设备详情

为了检查某个网络接口的详情,可以使用 device 子命令中的 show 操作。假如你不提供某个设备的名称,那么会获取并展示所有设备的详情。你可以上下翻动来查看这些信息。

要查看你最近添加的连接所对应的设备 enp0s8,你可以使用下面的命令,请注意验证它使用的 IP 地址是否为先前你要求设置的那个:

$ nmcli device show enp0s8
GENERAL.DEVICE:                         enp0s8
GENERAL.TYPE:                           ethernet
GENERAL.HWADDR:                         08:00:27:81:16:20
GENERAL.MTU:                            1500
GENERAL.STATE:                          100 (connected)
GENERAL.CONNECTION:                     ethernet-enp0s8
GENERAL.CON-PATH:                       /org/freedesktop/NetworkManager/ActiveConnection/6
WIRED-PROPERTIES.CARRIER:               on
IP4.ADDRESS[1]:                         192.168.4.26/24
IP4.GATEWAY:                            --
IP4.ROUTE[1]:                           dst = 192.168.4.0/24, nh = 0.0.0.0, mt = 103
IP6.ADDRESS[1]:                         fe80::6d70:90de:cb83:4491/64
IP6.GATEWAY:                            --
IP6.ROUTE[1]:                           dst = fe80::/64, nh = ::, mt = 103
IP6.ROUTE[2]:                           dst = ff00::/8, nh = ::, mt = 256, table=255

上面的输出非常细致,它主要显示了下面这些内容:

  • 网络接口名称,在这个示例中是 enp0s8,它是 udev 分配的
  • 网络连接类型,在这个示例中是物理的 Ethernet 连接
  • 设备的 媒介访问控制 media access control (MAC)地址,它被用来在网络中识别该设备
  • 最大传输单元,在单个传输中最大协议数据单位的大小,任何大于这个大小的数据将被分为多个包来进行传输
  • 该设备当前已经处于连接状态
  • 这个设备使用的连接名称是 ethernet-enp0s8
  • 这个设备使用的 IP 地址如上面所要求的那样,被设置为 192.168.4.26/24

其他的信息则是与这个设备连接的网络相关的默认路由和网关设置信息。

nmcli 的交互式编辑器

尽管 nmcli 是一个命令行工具,但它还包含一个基本的交互式编辑器,edit 子命令将为你指定的连接打开一个交互式编辑器,例如:

$ nmcli connection edit ethernet-enp0s8

它将显示少量的帮助文字,接着是 nmcli 的命令提示符:

===| nmcli interactive connection editor |===

Editing existing '802-3-ethernet' connection: 'ethernet-enp0s8'

Type 'help' or '?' for available commands.
Type 'print' to show all the connection properties.
Type 'describe [<setting>.<prop>]' for detailed property description.

You may edit the following settings: connection, 802-3-ethernet (ethernet), 802-1x, dcb, sriov, ethtool, match, ipv4, ipv6, tc, proxy
nmcli>

假如你输入 print 然后敲击 Enter 键, nmcli 将列举出与这个接口相关的所有属性。这些属性有很多,你可以上下翻动来查看这个列表:

===============================================================================
                 Connection profile details (ethernet-enp0s8)
===============================================================================
connection.id:                          ethernet-enp0s8
connection.uuid:                        09d26960-25a0-440f-8b20-c684d7adc2f5
connection.stable-id:                   --
connection.type:                        802-3-ethernet
connection.interface-name:              enp0s8
connection.autoconnect:                 yes
connection.autoconnect-priority:        0
connection.autoconnect-retries:         -1 (default)
connection.multi-connect:               0 (default)
connection.auth-retries:                -1
connection.timestamp:                   1593967212
connection.read-only:                   no
connection.permissions:                 --
connection.zone:                        --
connection.master:                      --
connection.slave-type:                  --
connection.autoconnect-slaves:          -1 (default)
connection.secondaries:                 --

如果你想将你的连接改为 DHCP,则请输入 goto ipv4 然后敲 Enter 键:

nmcli> goto ipv4
You may edit the following properties: method, dns, dns-search, dns-options, dns-priority, addresses, gateway, routes, route-metric, route-table, routing-rules, ignore-auto-routes, ignore-auto-dns, dhcp-client-id, dhcp-iaid, dhcp-timeout, dhcp-send-hostname, dhcp-hostname, dhcp-fqdn, dhcp-hostname-flags, never-default, may-fail, dad-timeout
nmcli ipv4>

你想改变的属性是 method,再继续敲 set method auto 然后敲 Enter 键:

nmcli ipv4> set method auto
Do you also want to clear 'ipv4.addresses'? [yes]:

假如你想让这个连接清除掉这个静态 IP 地址,则请敲 Enter 键,如果要保留,则输入 no 然后敲 Enter 键。假如你想在将来再次使用它,你可以保留这个 IP 地址。即便存储了一个静态的 IP 地址,如果 method 被设置为 auto ,它仍然会使用 DHCP。

最后输入 save 来保存你的更改:

nmcli ipv4> save
Connection 'ethernet-enp0s8' (09d26960-25a0-440f-8b20-c684d7adc2f5) successfully updated.
nmcli ipv4>

输入 quit 来离开 nmcli 的交互式编辑器窗口。假如你不想离开,可以输入 back 来回到最开始的命令行提示符界面,然后继续使用这个编辑器。

nmcli 的更多内容

浏览交互式编辑器,你就可以看到 nmcli 有多少设定和每个设定有多少属性。交互式编辑器是一个简洁的工具,但如果需要在命令行或者在脚本中使用 nmcli,你还是需要使用常规的命令行版本。

现在你有了这些基础知识,你还可以查看 nmcliman 页面 来查看它还可以提供什么更多功能。


via: https://opensource.com/article/20/7/nmcli

作者:Dave McKay 选题:lujun9972 译者:FSSLC 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

在 Linux 系统上,bash shell 的 history 命令可以方便地回顾和重用命令,但是你要控制它记住多少,忘记多少,有很多事情要做。

Linux 系统中的 bash history 命令有助于记住你以前运行过的命令,并重复这些命令,而不必重新输入。

如果可以的话,你肯定会很高兴不用翻阅十几页的手册,每过一会再次列出你的文件,而是通过输入 history 查看以前运行的命令。在这篇文章中,我们将探讨如何让 history 命令记住你希望它记住的内容,并忘记那些可能没有什么“历史价值”的命令。

查看你的命令历史

要查看以前运行过的命令,你只需输入 history。你可能会看到一长串命令。记忆的命令数量取决于在 ~/.bashrc 文件中设置的名为 $HISTSIZE 的环境变量,但是如果你想保存更多或更少的命令,你可以根据你的需要改变这个设置。

要查看历史记录,请使用 history 命令:

$ history
209 uname -v
210 date
211 man chage
...

要查看将显示的最大命令数量:

$ echo $HISTSIZE
500

你可以通过运行这样的命令来改变 $HISTSIZE 并使之永久化:

$ export HISTSIZE=1000
$ echo "HISTSIZE=1000" >> ~/.bashrc

在为你保留多少历史记录和当你输入 history 时显示多少历史记录之间也有区别。$HISTSIZE 变量控制显示多少历史记录,而 $HISTFILESIZE 变量控制在你的 .bash_history 文件中保留多少命令。

$ echo $HISTSIZE
1000
$ echo $HISTFILESIZE
2000

你可以通过计算历史文件中的行数来验证第二个变量:

$ wc -l .bash_history
2000 .bash_history

需要注意的是,在登录会话中输入的命令在注销前不会被添加到你的 .bash_history 文件中,尽管它们会立即显示在 history 命令输出中。

使用历史

有三种方法可以重发你在 history 中发现的命令。最简单的方法,特别是当你想重用的命令是最近运行的时候,通常是输入一个 ! 后面跟上命令中足够多的首字母来唯一地识别它。

$ !u
uname -v
#37-Ubuntu SMP Thu Mar 26 20:41:27 UTC 2020

另一种简单的重复命令的方法是,只需按上箭头键,直到显示了该命令,然后按回车键。

另外,如果你运行 history 命令,并看到你想重新运行的命令被列出,你可以输入一个 ! 后面跟着命令左边显示的序号。

$ !209
uname -v
#37-Ubuntu SMP Thu Mar 26 20:41:27 UTC 2020

隐藏历史

如果你想在一段时间内停止记录命令,你可以使用这个命令:

$ set +o history

当你输入 history 时,你输入的命令不会显示出来,当你退出会话或退出终端时,它们也不会被添加到你的 .bash_history 文件中。

要取消这个设置,使用 set -o history

要使它永久化,你可以把它添加到你的 .bashrc 文件中,尽管不使用命令历史记录通常不是一个好主意。

$ echo 'set +o history' >> ~/.bashrc

要暂时清除历史记录,这样在输入 history 时只显示之后输入的命令,可以使用 history -c(清除)命令:

$ history | tail -3
209 uname -v
210 date
211 man chage
$ history -c
$ history
1  history

注意:在输入 history -c 后输入的命令不会被添加到 .bash_history 文件中。

控制历史

许多系统上的 history 命令的设置会默认包括一个名为 $HISTCONTROL 的变量,以确保即使你连续运行同一命令七次,也只会被记住一次。它还可以确保你在首先输入一个或多个空格后跟着的命令将从你的命令历史记录中忽略。

$ grep HISTCONTROL .bashrc
HISTCONTROL=ignoreboth

ignoreboth 的意思是“忽略重复的命令和以空格开头的命令”。例如,如果你输入这些命令:

$ echo try this
$ date
$ date
$ date
$   pwd
$ history

你的 history 命令应该像这样报告:

$ history
$ echo try this
$ date
$ history

请注意,连续的 date 命令被缩减为一条,以空格缩进的命令被省略。

忽略历史

要忽略某些命令,使它们在你输入 history 时不会出现,也不会被添加到你的 .bash_history 文件中,可以使用 $HISTIGNORE 设置。例如:

$ export HISTIGNORE=”history:cd:exit:ls:pwd:man”

这个设置将导致所有的 historycdexitlspwdman 命令从你的 history 命令的输出和 .bash_history 文件中被忽略。

如果你想把这个设置变成永久性的,你必须把它添加到你的 .bashrc 文件中。

$ echo 'HISTIGNORE="history:cd:exit:ls:pwd:man"' >> .bashrc

这个设置只是意味着当你回看以前运行的命令时,列表不会被你在查看命令历史记录时不想看到的命令所干扰。

记住、忽略和忘记过去的命令

命令历史记录很有用,因为它可以帮助你记住最近使用过的命令,并提醒你最近所做的更改。它还可以让你更容易地重新运行命令,特别是那些有一串参数但你不一定想重新创建的命令。定制你的历史设置可以让你对命令历史的使用变得更容易,更有效率。


via: https://www.networkworld.com/article/3537214/tweaking-history-on-linux.html

作者:Sandra Henry-Stocker 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

基本上所有正而八经的算法教材都会解释像 快速排序 quicksort 堆排序 heapsort 这样的排序算法有多快,但并不需要复杂的数学就能证明你可以逐渐趋近的速度有多快。

关于标记的一个严肃说明:

大多数计算机专业的科学家使用大写字母 O 标记来指代“趋近,直到到达一个常数比例因子”,这与数学专业所指代的意义是有所区别的。这里我使用的大 O 标记的含义与计算机教材所指相同,但至少不会和其他数学符号混用。

基于比较的排序

先来看个特例,即每次比较两个值大小的算法(快速排序、堆排序,及其它通用排序算法)。这种思想后续可以扩展至所有排序算法。

一个简单的最差情况下的计数角度

假设有 4 个互不相等的数,且顺序随机,那么,可以通过只比较一对数字完成排序吗?显然不能,证明如下:根据定义,要对该数组排序,需要按照某种顺序重新排列数字。换句话说,你需要知道用哪种排列方式?有多少种可能的排列?第一个数字可以放在四个位置中的任意一个,第二个数字可以放在剩下三个位置中的任意一个,第三个数字可以放在剩下两个位置中的任意一个,最后一个数字只有剩下的一个位置可选。这样,共有 4×3×2×1=4!=24 种排列可供选择。通过一次比较大小,只能产生两种可能的结果。如果列出所有的排列,那么“从小到大”排序对应的可能是第 8 种排列,按“从大到小”排序对应的可能是第 24 种排列,但无法知道什么时候需要的是其它 22 种排列。

通过 2 次比较,可以得到 2×2=4 种可能的结果,这仍然不够。只要比较的次数少于 5(对应 2 5 = 32 种输出),就无法完成 4 个随机次序的数字的排序。如果 W(N) 是最差情况下对 N 个不同元素进行排序所需要的比较次数,那么,

两边取以 2 为底的对数,得:

N! 的增长近似于 N<sup> N</sup> (参阅 Stirling 公式),那么,

这就是最差情况下从输出计数的角度得出的 O(N log N) 上限。

从信息论角度的平均状态的例子

使用一些信息论知识,就可以从上面的讨论中得到一个更有力的结论。下面,使用排序算法作为信息传输的编码器:

  1. 任取一个数,比如 15
  2. 从 4 个数字的排列列表中查找第 15 种排列
  3. 对这种排列运行排序算法,记录所有的“大”、“小”比较结果
  4. 用二进制编码发送比较结果
  5. 接收端重新逐步执行发送端的排序算法,需要的话可以引用发送端的比较结果
  6. 现在接收端就可以知道发送端如何重新排列数字以按照需要排序,接收端可以对排列进行逆算,得到 4 个数字的初始顺序
  7. 接收端在排列表中检索发送端的原始排列,指出发送端发送的是 15

确实,这有点奇怪,但确实可以。这意味着排序算法遵循着与编码方案相同的定律,包括理论所证明的不存在通用的数据压缩算法。算法中每次比较发送 1 比特的比较结果编码数据,根据信息论,比较的次数至少是能表示所有数据的二进制位数。更技术语言点,平均所需的最小比较次数是输入数据的香农熵,以比特为单位。熵是衡量信息等不可预测量的数学度量。

包含 N 个元素的数组,元素次序随机且无偏时的熵最大,其值为 log<sub> 2</sub>​ N! 个比特。这证明 O(N log N) 是一个基于比较的对任意输入排序的最优平均值。

以上都是理论说法,那么实际的排序算法如何做比较的呢?下面是一个数组排序所需比较次数均值的图。我比较的是理论值与快速排序及 Ford-Johnson 合并插入排序 的表现。后者设计目的就是最小化比较次数(整体上没比快速排序快多少,因为生活中相对于最大限度减少比较次数,还有更重要的事情)。又因为 合并插入排序 merge-insertion sort 是在 1959 年提出的,它一直在调整,以减少了一些比较次数,但图示说明,它基本上达到了最优状态。

一点点理论导出这么实用的结论,这感觉真棒!

小结

证明了:

  1. 如果数组可以是任意顺序,在最坏情况下至少需要 O(N log N) 次比较。
  2. 数组的平均比较次数最少是数组的熵,对随机输入而言,其值是 O(N log N)

注意,第 2 个结论允许基于比较的算法优于 O(N log N),前提是输入是低熵的(换言之,是部分可预测的)。如果输入包含很多有序的子序列,那么合并排序的性能接近 O(N)。如果在确定一个位之前,其输入是有序的,插入排序性能接近 O(N)。在最差情况下,以上算法的性能表现都不超出 O(N log N)

一般排序算法

基于比较的排序在实践中是个有趣的特例,但从理论上讲,计算机的 CMP 指令与其它指令相比,并没有什么特别之处。在下面两条的基础上,前面两种情形都可以扩展至任意排序算法:

  1. 大多数计算机指令有多于两个的输出,但输出的数量仍然是有限的。
  2. 一条指令有限的输出意味着一条指令只能处理有限的熵。

这给出了 O(N log N) 对应的指令下限。任何物理上可实现的计算机都只能在给定时间内执行有限数量的指令,所以算法的执行时间也有对应 O(N log N) 的下限。

什么是更快的算法?

一般意义上的 O(N log N) 下限,放在实践中来看,如果听人说到任何更快的算法,你要知道,它肯定以某种方式“作弊”了,其中肯定有圈套,即它不是一个可以处理任意大数组的通用排序算法。可能它是一个有用的算法,但最好看明白它字里行间隐含的东西。

一个广为人知的例子是 基数排序 radix sort 算法,它经常被称为 O(N) 排序算法,但它只能处理所有数字都能放入 k 比特的情况,所以实际上它的性能是 O(kN)

什么意思呢?假如你用的 8 位计算机,那么 8 个二进制位可以表示 2 8=256 个不同的数字,如果数组有上千个数字,那么其中必有重复。对有些应用而言这是可以的,但对有些应用就必须用 16 个二进制位来表示,16 个二进制位可以表示 2 16=65,536 个不同的数字。32 个二进制位可以表示 2 32=4,294,967,296 不同的数字。随着数组长度的增长,所需要的二进制位数也在增长。要表示 N 个不同的数字,需要 k ≥ log<sub> 2</sub>​ N 个二进制位。所以,只有允许数组中存在重复的数字时, O(kN) 才优于 O(N log N)

一般意义上输入数据的 O(N log N) 的性能已经说明了全部问题。这个讨论不那么有趣因为很少需要在 32 位计算机上对几十亿整数进行排序,如果有谁的需求超出了 64 位计算机的极限,他一定没有告诉别人


via: https://theartofmachinery.com/2019/01/05/sorting_is_nlogn.html

作者:Simon Arneaud 选题:lujun9972 译者:silentdawn-zz 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

集中日志并结构化待处理的日志数据可缓解与缺少日志相关的风险

日志记录和日志分析对于保护基础设施安全来说至关重要,尤其是当我们考虑到通用漏洞的时候。这篇文章基于我在 FOSDEM'19 上的闪电秀《Let's use centralized log collection to make incident response teams happy》,目的是提高大家对日志匮乏这种安全问题的重视,提供一种避免风险的方法,并且倡议更多的安全实践(利益声明: 我为 NXLog 工作)。

为什么要收集日志?为什么要集中日志记录?

确切的说,日志是写入磁盘的仅追加的记录序列。在实际生活中,日志可以在你尝试寻找异常的根源时帮助你调查基础设施的问题。当你有多个使用自己的标准与格式的日志的异构系统,并且想用一种可靠的方法来接收和处理它们的时候,挑战就来临了。这通常以元数据为代价的。集中日志记录解决方案需要共性,这种共性常常会去除许多开源日志记录工具所提供的丰富的元数据。

日志记录与监控匮乏的安全风险

开源 Web 应用程序安全项目 Open Web Application Security Project OWASP)是一个为业界贡献了许多杰出项目(包括许多专注于软件安全的工具)的非营利组织。OWASP 定期为应用开发人员和维护者报告最危险的安全挑战。在最新一版《10 项最严重的 Web 应用程序安全风险》中,OWASP 将日志记录和监控匮乏加入了列表中。OWASP 警告下列情况会导致日志记录、检测、监控和主动响应的匮乏:

  • 未记录重要的可审计性事件,如:登录、登录失败和高额交易。
  • 告警和错误事件未能产生、产生不足或不清晰的日志信息。
  • 日志信息仅在本地存储。
  • 对于实时或准实时的主动攻击,应用程序无法检测、处理和告警。

可以通过集中日志记录(例如,不仅将日志本地存储)和结构化日志数据以进一步分析来缓解上述情形(例如,在告警仪表盘和安全套件中)。

举例来说, 假设一个 DNS 查询会导向名为 hacked.badsite.net 的恶意网站。通过 DNS 监控,管理员监控并且主动的分析 DNS 请求与响应。DNS 监控的效果依赖于充足的日志记录与收集来发现潜在问题,同样也依赖于结构化 DNS 日志的结果来进一步分析。

2019-01-29
Time (GMT)      Source                  Destination             Protocol-Info
12:42:42.112898 SOURCE_IP               xxx.xx.xx.x             DNS     Standard query 0x1de7  A hacked.badsite.net

你可以在 NXLog 社区版 中自己尝试一下这个例子,也可以尝试其他例子和代码片段。 (再次声明:我为 NXLog 工作)

重要的一点:非结构化数据与结构化数据

花费一点时间来考虑下日志数据格式是很重要的。例如,让我们来考虑以下日志消息:

debug1: Failed password for invalid user amy from SOURCE_IP port SOURCE_PORT ssh2

这段日志包含了一个预定义的结构,例如冒号前面的元数据关键词(debug1)然而,余下的日志字段是一个未结构化的字符串(Failed password for invalid user amy from SOURCE_IP port SOURCE_PORT ssh2)。因此,即便这个消息是人类可轻松阅读的格式,但它不是一个计算机容易解析的格式。

非结构化的事件数据存在局限性,包括难以解析、搜索和分析日志。重要的元数据通常以一种自由字符串的形式作为非结构化数据字段,就像上面的例子一样。日志管理员会在他们尝试标准化/归一化日志数据与集中日志源的过程中遇到这个问题。

接下来怎么做

除了集中和结构化日志之外,确保你收集了正确的日志数据——Sysmon、PowerShell、Windows 事件日志、DNS 调试日志、ETW、内核监控、文件完整性监控、数据库日志、外部云日志等等。同样也要选用适当的工具和流程来来收集、汇总和帮助理解数据。

希望这对你从不同日志源中集中日志收集提供了一个起点:将日志发送到仪表盘、监控软件、分析软件以及像安全性资讯与事件管理(SIEM)套件等外部源。

你的集中日志策略会是怎么样?请在评论中分享你的想法。


via: https://opensource.com/article/19/2/reducing-security-risks-centralized-logging

作者:Hannah Suarez 选题:lujun9972 译者:leommxj 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

在 Linux 相关的文章、新闻和讨论中,你会经常遇到 显示服务器 display server 、Xorg、Wayland 等名词。

在这篇解释文章中,我将讨论 Linux 中的显示服务器。

什么是显示服务器?

显示服务器是一个程序,它负责协调其客户端与操作系统的其他部分之间,以及硬件和操作系统之间的输入和输出。基本上,多亏了显示服务器,你才能以图形化的方式使用你的计算机(GUI)。如果没有显示服务器,你只能局限于命令行界面(TTY)。

显示服务器提供了一个图形环境的框架,使你可以使用鼠标和键盘与应用程序进行交互。

显示服务器通过显示服务器协议(如 X11)与客户端进行通信。显示服务器是图形用户界面 —— 特别是窗口系统 —— 中的一个关键组件。

不要把显示服务器和桌面环境混淆。桌面环境的下层使用的是显示服务器。

听起来很熟悉,但又不完全清楚?让我来解释一下。

Linux 上的显示服务器协议

Linux 中有三种显示服务器协议,分别是 X11、Wayland 和 Mir。下面我就给大家简单介绍一下这些显示服务器。

X11

X11(也称 X)是已经存在多年的传统显示服务器。它是 Linux 发行版中最常用的显示服务器。

X 架构

X11 通信协议,使用显示服务器 X.org 服务器。它接收来自设备驱动程序的输入事件,并将它们提供给它的一个客户端。

显示服务器也从客户端接收数据,它处理数据并进行合成,在 Linux 上,它将数据传递给三个内核组件之一:DRMgemKMS 驱动

X.Org 服务器是一个显示服务器,它依靠第二个程序:合成窗口管理器,来进行合成。例如 Mutter) 或 KWin。GNOME 使用的是 Mutter。

Wayland

按照其网站的说法,Wayland “旨在作为 X 的更简单的替代品,更容易开发和维护”。

而事实上 Wayland 就是现代的显示服务器,它应该取代传统的 X 显示服务器。

对它的采用还在普及中。Ubuntu 曾试图在 17.10 版本中改用 Wayland 作为默认的显示服务器,但这个尝试遭到了负面反馈。

很多 GUI 应用程序及其框架都依赖于 X 服务器。这些应用程序在 Wayland 上无法正常工作。

这迫使 Ubuntu 继续使用 X 作为默认显示服务器。它仍然提供了使用 Wayland 的选项,但不再是默认的了。

即使在今天,绝大多数的发行版都默认使用 X 显示服务器。

Wayland 架构

实施 Wayland 显示服务器协议的显示服务器,被称为 Wayland 合成器。和 X11 上的一样,Wayland 合成器负责处理其客户端的输入和输出,但同时也进行合成,这与 X11 相反。

几个 Wayland 合成器是 Weston)、Mutter)、KWinEnlightenment)。

Mir

Mir 显示服务器自带的 Mir 显示服务器协议,与 X11 和 Wayland 使用的协议不同。它是由 Canonical 开发的,作为 Unity 开发的一部分,打算成为 Ubuntu 的首选显示服务器。

但在 2017 年,它已经被 [Ubuntu] 桌面版的 Wayland 显示服务器所取代,不过 Mir 的开发还在继续,用于物联网(IoT)应用。

为什么我们还在使用 Xorg?

Wayland 作为比较新的产品,相比 Xorg 来说,还不是很稳定。作为客户端的程序,必须知道如何与显示服务器进行通信。

因此,很多程序在使用 Wayland 时可能无法运行。Ubuntu 默认切换到 Wayland 的实验证实了这一点。

结束语

我希望你对 Linux 中的显示服务器概念有了更好的理解。我已经尽量不谈太多的技术细节,但我无法完全避免。

欢迎你的反馈和建议。


via: https://itsfoss.com/display-server/

作者:Dimitrios Savvopoulos 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

在问题导致关键的微服务瘫痪之前,使用 GraphQL 的监控功能帮助你及早发现问题。

微服务GraphQL 就像面包和黄油一样,是一个很好的组合。它们本身都很棒,结合起来就更棒了。了解你的微服务的健康状况是很重要的,因为它们运行着重要的服务。如果等到某个关键的服务崩溃了才诊断问题,那是很愚蠢的。让 GraphQL 帮助你及早发现问题并不需要花费太多精力。

 title=

常规的健康检查可以让你观察和测试你的服务,在问题影响到你的业务、客户或项目之前,尽早得到通知。说起来很简单,但健康检查到底要做什么呢?

以下是我在设计服务检查时考虑的因素:

服务器健康检查的要求:

  1. 我需要了解我的微服务的可用性状态。
  2. 我希望能够管理服务器的负载。
  3. 我希望对我的微服务进行端到端(e2e)测试。
  4. 我应该能够预测中断。

 title=

做服务器健康检查的方法

进行健康检查可能比较棘手,因为理论上,你可以检查的东西几乎是无穷无尽的。我喜欢从小处着手,运行最基本的测试:ping 测试。这只是测试运行应用的服务器是否可用。然后,我加强测试以评估特定问题,思考服务器中最重要的元素。我想到那些如果突然消失的话将是灾难性的事情。

  1. **Ping 检查:**Ping 是最简单的监控类型。它只是检查你的应用是否在线。
  2. **脚本化浏览器:**脚本化浏览器比较高级。像 Selenium 这样的浏览器自动化工具可以让你实现自定义的监控规则集。
  3. **API 测试:**API 测试用于监控 API 端点。这是 ping 检查模型的高级版本,你可以根据 API 响应来定义监控计划。

使用 GraphQL 进行健康检查

在一个典型的基于 REST 的微服务中,你需要从头开始构建健康检查功能。这是一个时间密集型的过程,但使用 GraphQL 就不用担心了。

根据它的网站称:

“GraphQL 是一种用于 API 的查询语言,也是一种用现有数据完成这些查询的运行时环境。GraphQL 为你的 API 中的数据提供了一个完整的、可理解的描述,让客户有能力精确地仅查询他们所需要的东西,让 API 更容易随着时间的推移而进化,并实现强大的开发者工具。”

当你启动一个 GraphQL 微服务时,你还可以获得监控微服务的运行状况的供给。这是一个隐藏的宝贝。

正如我上面提到的,你可以用 GraphQL 端点执行 API 测试以及 ping 检查。

Apollo GraphQL 服务器提供了一个默认的端点,它可以返回有关你的微服务和服务器健康的信息。它不是很复杂:如果服务器正在运行,它就会返回状态码 200。

默认端点是 <server-host>/.well-known/apollo/server-health

 title=

高级健康检查

在某些情况下,基本的健康检查可能不足以确保系统的完整性。例如,紧密耦合的系统需要更多的业务逻辑来确保系统的健康。

Apollo GraphQL 在定义服务器的同时,通过声明一个 onHealthCheck 函数来有效地管理这种情况。

* Defining the Apollo Server */
const apollo = new ApolloServer({
  playground: process.env.NODE_ENV !== 'production',
  typeDefs: gqlSchema,
  resolvers: resolver,
  onHealthCheck: () => {
    return new Promise((resolve, reject) => {
      // Replace the `true` in this conditional with more specific checks!
      if (true) {
        resolve();
      } else {
        reject();
      }
    });
  }
});

当你定义一个 onHealthCheck 方法时,它返回一个 promise,如果服务器准备好了,它就会返回 resolve,如果有错误,它就会返回 reject

GraphQL 让监控 API 变得更容易。此外,在你的服务器基础架构中使用它可以使代码变得可扩展。如果你想尝试采用 GraphQL 作为你的新基础设施定义,请参见我的 GitHub 仓库中的示例代码和配置


via: https://opensource.com/article/20/8/microservices-graphql

作者:Rigin Oommen 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出