分类 技术 下的文章

如果你使用过 top 命令来查看 Fedora 系统中的内存使用情况,你可能会惊讶,看起来消耗的数量比系统可用的内存更多。下面会详细介绍内存使用情况以及如何理解这些数据。

内存实际使用情况

操作系统对内存的使用方式并不是太通俗易懂。事实上,其背后有很多不为人知的巧妙技术在发挥着作用。通过这些方式,可以在无需用户干预的情况下,让操作系统更有效地使用内存。

大多数应用程序都不是系统自带的,但每个应用程序都依赖于安装在系统中的库中的一些函数集。在 Fedora 中,RPM 包管理系统能够确保在安装应用程序时也会安装所依赖的库。

当应用程序运行时,操作系统并不需要将它要用到的所有信息都加载到物理内存中。而是会为存放代码的存储空间构建一个映射,称为虚拟内存。操作系统只把需要的部分加载到内存中,当某一个部分不再需要后,这一部分内存就会被释放掉。

这意味着应用程序可以映射大量的虚拟内存,而使用较少的系统物理内存。特殊情况下,映射的虚拟内存甚至可以比系统实际可用的物理内存更多!而且在操作系统中这种情况也并不少见。

另外,不同的应用程序可能会对同一个库都有依赖。Fedora 中的 Linux 内核通常会在各个应用程序之间共享内存,而不需要为不同应用分别加载同一个库的多个副本。类似地,对于同一个应用程序的不同实例也是采用这种方式共享内存。

如果不首先了解这些细节,top 命令显示的数据可能会让人摸不着头脑。下面就举例说明如何正确查看内存使用量。

使用 top 命令查看内存使用量

如果你还没有使用过 top 命令,可以打开终端直接执行查看。使用 Shift + M 可以按照内存使用量来进行排序。下图是在 Fedora Workstation 中执行的结果,在你的机器上显示的结果可能会略有不同:

主要通过以下三列来查看内存使用情况:VIRTRESSHR。目前以 KB 为单位显示相关数值。

VIRT 列代表该进程映射的 虚拟 virtual 内存。如上所述,虚拟内存不是实际消耗的物理内存。例如, GNOME Shell 进程 gnome-shell 实际上没有消耗超过 3.1 GB 的物理内存,但它对很多更低或更高级的库都有依赖,系统必须对每个库都进行映射,以确保在有需要时可以加载这些库。

RES 列代表应用程序消耗了多少实际( 驻留 resident )内存。对于 GNOME Shell 大约是 180788 KB。例子中的系统拥有大约 7704 MB 的物理内存,因此内存使用率显示为 2.3%。

但根据 SHR 列显示,其中至少有 88212 KB 是 共享 shared 内存,这部分内存可能是其它应用程序也在使用的库函数。这意味着 GNOME Shell 本身大约有 92 MB 内存不与其他进程共享。需要注意的是,上述例子中的其它程序也共享了很多内存。在某些应用程序中,共享内存在内存使用量中会占很大的比例。

值得一提的是,有时进程之间通过内存通信,这些内存也是共享的,但 top 这样的工具却不一定能检测到,所以以上的说明也不一定准确。

关于交换分区

系统还可以通过交换分区来存储数据(例如硬盘),但读写的速度相对较慢。当物理内存渐渐用满,操作系统就会查找内存中暂时不会使用的部分,将其写出到交换区域等待需要的时候使用。

因此,如果交换内存的使用量一直偏高,表明系统的物理内存已经供不应求了。有时候一个不正常的应用也有可能导致出现这种情况,但如果这种现象经常出现,就需要考虑提升物理内存或者限制某些程序的运行了。

感谢 Stig NygaardFlickr 上提供的图片(CC BY 2.0)。


via: https://fedoramagazine.org/understand-fedora-memory-usage-top/

作者:Paul W. Frields 选题:lujun9972 译者:HankChow 校对:wxy

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

tcpdump 是一个有名的命令行数据包分析工具。我们可以使用 tcpdump 命令捕获实时 TCP/IP 数据包,这些数据包也可以保存到文件中。之后这些捕获的数据包可以通过 tcpdump 命令进行分析。tcpdump 命令在网络层面进行故障排除时变得非常方便。

tcpdump 在大多数 Linux 发行版中都能用,对于基于 Debian 的Linux,可以使用 apt 命令安装它。

# apt install tcpdump -y

在基于 RPM 的 Linux 操作系统上,可以使用下面的 yum 命令安装 tcpdump

# yum install tcpdump -y

当我们在没用任何选项的情况下运行 tcpdump 命令时,它将捕获所有接口的数据包。因此,要停止或取消 tcpdump 命令,请键入 ctrl+c。在本教程中,我们将使用不同的实例来讨论如何捕获和分析数据包。

示例:1)从特定接口捕获数据包

当我们在没用任何选项的情况下运行 tcpdump 命令时,它将捕获所有接口上的数据包,因此,要从特定接口捕获数据包,请使用选项 -i,后跟接口名称。

语法:

# tcpdump -i {接口名}

假设我想从接口 enp0s3 捕获数据包。

输出将如下所示,

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
06:43:22.905890 IP compute-0-1.example.com.ssh > 169.144.0.1.39374: Flags [P.], seq 21952160:21952540, ack 13537, win 291, options [nop,nop,TS val 26164373 ecr 6580205], length 380
06:43:22.906045 IP compute-0-1.example.com.ssh > 169.144.0.1.39374: Flags [P.], seq 21952540:21952760, ack 13537, win 291, options [nop,nop,TS val 26164373 ecr 6580205], length 220
06:43:22.906150 IP compute-0-1.example.com.ssh > 169.144.0.1.39374: Flags [P.], seq 21952760:21952980, ack 13537, win 291, options [nop,nop,TS val 26164373 ecr 6580205], length 220
06:43:22.906291 IP 169.144.0.1.39374 > compute-0-1.example.com.ssh: Flags [.], ack 21952980, win 13094, options [nop,nop,TS val 6580205 ecr 26164373], length 0
06:43:22.906303 IP 169.144.0.1.39374 > compute-0-1.example.com.ssh: Flags [P.], seq 13537:13609, ack 21952980, win 13094, options [nop,nop,TS val 6580205 ecr 26164373], length 72
06:43:22.906322 IP compute-0-1.example.com.ssh > 169.144.0.1.39374: Flags [P.], seq 21952980:21953200, ack 13537, win 291, options [nop,nop,TS val 26164373 ecr 6580205], length 220
^C
109930 packets captured
110065 packets received by filter
133 packets dropped by kernel
[[email protected] ~]#

示例:2)从特定接口捕获特定数量数据包

假设我们想从特定接口(如 enp0s3)捕获 12 个数据包,这可以使用选项 -c {数量} -I {接口名称} 轻松实现。

root@compute-0-1 ~]# tcpdump -c 12 -i enp0s3

上面的命令将生成如下所示的输出,

N-Number-Packsets-tcpdump-interface

示例:3)显示 tcpdump 的所有可用接口

使用 -D 选项显示 tcpdump 命令的所有可用接口,

[root@compute-0-1 ~]# tcpdump -D
1.enp0s3
2.enp0s8
3.ovs-system
4.br-int
5.br-tun
6.nflog (Linux netfilter log (NFLOG) interface)
7.nfqueue (Linux netfilter queue (NFQUEUE) interface)
8.usbmon1 (USB bus number 1)
9.usbmon2 (USB bus number 2)
10.qbra692e993-28
11.qvoa692e993-28
12.qvba692e993-28
13.tapa692e993-28
14.vxlan_sys_4789
15.any (Pseudo-device that captures on all interfaces)
16.lo [Loopback]
[[email protected] ~]#

我正在我的一个 openstack 计算节点上运行 tcpdump 命令,这就是为什么在输出中你会看到数字接口、标签接口、网桥和 vxlan 接口

示例:4)捕获带有可读时间戳的数据包(-tttt 选项)

默认情况下,在 tcpdump 命令输出中,不显示可读性好的时间戳,如果您想将可读性好的时间戳与每个捕获的数据包相关联,那么使用 -tttt 选项,示例如下所示,

[[email protected] ~]# tcpdump -c 8 -tttt -i enp0s3
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
2018-08-25 23:23:36.954883 IP compute-0-1.example.com.ssh > 169.144.0.1.39406: Flags [P.], seq 1449206247:1449206435, ack 3062020950, win 291, options [nop,nop,TS val 86178422 ecr 21583714], length 188
2018-08-25 23:23:36.955046 IP 169.144.0.1.39406 > compute-0-1.example.com.ssh: Flags [.], ack 188, win 13585, options [nop,nop,TS val 21583717 ecr 86178422], length 0
2018-08-25 23:23:37.140097 IP controller0.example.com.amqp > compute-0-1.example.com.57818: Flags [P.], seq 814607956:814607964, ack 2387094506, win 252, options [nop,nop,TS val 86172228 ecr 86176695], length 8
2018-08-25 23:23:37.140175 IP compute-0-1.example.com.57818 > controller0.example.com.amqp: Flags [.], ack 8, win 237, options [nop,nop,TS val 86178607 ecr 86172228], length 0
2018-08-25 23:23:37.355238 IP compute-0-1.example.com.57836 > controller0.example.com.amqp: Flags [P.], seq 1080415080:1080417400, ack 1690909362, win 237, options [nop,nop,TS val 86178822 ecr 86163054], length 2320
2018-08-25 23:23:37.357119 IP controller0.example.com.amqp > compute-0-1.example.com.57836: Flags [.], ack 2320, win 1432, options [nop,nop,TS val 86172448 ecr 86178822], length 0
2018-08-25 23:23:37.357545 IP controller0.example.com.amqp > compute-0-1.example.com.57836: Flags [P.], seq 1:22, ack 2320, win 1432, options [nop,nop,TS val 86172449 ecr 86178822], length 21
2018-08-25 23:23:37.357572 IP compute-0-1.example.com.57836 > controller0.example.com.amqp: Flags [.], ack 22, win 237, options [nop,nop,TS val 86178825 ecr 86172449], length 0
8 packets captured
134 packets received by filter
69 packets dropped by kernel
[[email protected] ~]#

示例:5)捕获数据包并将其保存到文件(-w 选项)

使用 tcpdump 命令中的 -w 选项将捕获的 TCP/IP 数据包保存到一个文件中,以便我们可以在将来分析这些数据包以供进一步分析。

语法:

# tcpdump -w 文件名.pcap -i {接口名}

注意:文件扩展名必须为 .pcap

假设我要把 enp0s3 接口捕获到的包保存到文件名为 enp0s3-26082018.pcap

[root@compute-0-1 ~]# tcpdump -w enp0s3-26082018.pcap -i enp0s3

上述命令将生成如下所示的输出,

[root@compute-0-1  ~]# tcpdump -w enp0s3-26082018.pcap -i enp0s3
tcpdump: listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
^C841 packets captured
845 packets received by filter
0 packets dropped by kernel
[root@compute-0-1  ~]# ls
anaconda-ks.cfg enp0s3-26082018.pcap
[root@compute-0-1  ~]#

捕获并保存大小大于 N 字节的数据包。

[root@compute-0-1  ~]# tcpdump -w enp0s3-26082018-2.pcap greater 1024

捕获并保存大小小于 N 字节的数据包。

[root@compute-0-1  ~]# tcpdump -w enp0s3-26082018-3.pcap less 1024

示例:6)从保存的文件中读取数据包(-r 选项)

在上面的例子中,我们已经将捕获的数据包保存到文件中,我们可以使用选项 -r 从文件中读取这些数据包,例子如下所示,

[root@compute-0-1 ~]# tcpdump -r enp0s3-26082018.pcap

用可读性高的时间戳读取包内容,

[root@compute-0-1  ~]# tcpdump -tttt -r enp0s3-26082018.pcap
reading from file enp0s3-26082018.pcap, link-type EN10MB (Ethernet)
2018-08-25 22:03:17.249648 IP compute-0-1.example.com.ssh > 169.144.0.1.39406: Flags [P.], seq 1426167803:1426167927, ack 3061962134, win 291, options
[nop,nop,TS val 81358717 ecr 20378789], length 124
2018-08-25 22:03:17.249840 IP 169.144.0.1.39406 > compute-0-1.example.com.ssh: Flags [.], ack 124, win 564, options [nop,nop,TS val 20378791 ecr 81358
717], length 0
2018-08-25 22:03:17.454559 IP controller0.example.com.amqp > compute-0-1.example.com.57836: Flags [.], ack 1079416895, win 1432, options [nop,nop,TS v
al 81352560 ecr 81353913], length 0
2018-08-25 22:03:17.454642 IP compute-0-1.example.com.57836 > controller0.example.com.amqp: Flags [.], ack 1, win 237, options [nop,nop,TS val 8135892
2 ecr 81317504], length 0
2018-08-25 22:03:17.646945 IP compute-0-1.example.com.57788 > controller0.example.com.amqp: Flags [.], seq 106760587:106762035, ack 688390730, win 237
, options [nop,nop,TS val 81359114 ecr 81350901], length 1448
2018-08-25 22:03:17.647043 IP compute-0-1.example.com.57788 > controller0.example.com.amqp: Flags [P.], seq 1448:1956, ack 1, win 237, options [nop,no
p,TS val 81359114 ecr 81350901], length 508
2018-08-25 22:03:17.647502 IP controller0.example.com.amqp > compute-0-1.example.com.57788: Flags [.], ack 1956, win 1432, options [nop,nop,TS val 813
52753 ecr 81359114], length 0
.........................................................................................................................

示例:7)仅捕获特定接口上的 IP 地址数据包(-n 选项)

使用 tcpdump 命令中的 -n 选项,我们能只捕获特定接口上的 IP 地址数据包,示例如下所示,

[root@compute-0-1 ~]# tcpdump -n -i enp0s3

上述命令输出如下,

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
22:22:28.537904 IP 169.144.0.20.ssh > 169.144.0.1.39406: Flags [P.], seq 1433301395:1433301583, ack 3061976250, win 291, options [nop,nop,TS val 82510005 ecr 20666610], length 188
22:22:28.538173 IP 169.144.0.1.39406 > 169.144.0.20.ssh: Flags [.], ack 188, win 9086, options [nop,nop,TS val 20666613 ecr 82510005], length 0
22:22:28.538573 IP 169.144.0.20.ssh > 169.144.0.1.39406: Flags [P.], seq 188:552, ack 1, win 291, options [nop,nop,TS val 82510006 ecr 20666613], length 364
22:22:28.538736 IP 169.144.0.1.39406 > 169.144.0.20.ssh: Flags [.], ack 552, win 9086, options [nop,nop,TS val 20666613 ecr 82510006], length 0
22:22:28.538874 IP 169.144.0.20.ssh > 169.144.0.1.39406: Flags [P.], seq 552:892, ack 1, win 291, options [nop,nop,TS val 82510006 ecr 20666613], length 340
22:22:28.539042 IP 169.144.0.1.39406 > 169.144.0.20.ssh: Flags [.], ack 892, win 9086, options [nop,nop,TS val 20666613 ecr 82510006], length 0
22:22:28.539178 IP 169.144.0.20.ssh > 169.144.0.1.39406: Flags [P.], seq 892:1232, ack 1, win 291, options [nop,nop,TS val 82510006 ecr 20666613], length 340
22:22:28.539282 IP 169.144.0.1.39406 > 169.144.0.20.ssh: Flags [.], ack 1232, win 9086, options [nop,nop,TS val 20666614 ecr 82510006], length 0
22:22:28.539479 IP 169.144.0.20.ssh > 169.144.0.1.39406: Flags [P.], seq 1232:1572, ack 1, win 291, options [nop,nop,TS val 82510006 ecr 20666614], length 340
22:22:28.539595 IP 169.144.0.1.39406 > 169.144.0.20.ssh: Flags [.], ack 1572, win 9086, options [nop,nop,TS val 20666614 ecr 82510006], length 0
22:22:28.539760 IP 169.144.0.20.ssh > 169.144.0.1.39406: Flags [P.], seq 1572:1912, ack 1, win 291, options [nop,nop,TS val 82510007 ecr 20666614], length 340
.........................................................................

您还可以使用 tcpdump 命令中的 -c-N 选项捕获 N 个 IP 地址包,

[root@compute-0-1  ~]# tcpdump -c 25 -n -i enp0s3

示例:8)仅捕获特定接口上的 TCP 数据包

tcpdump 命令中,我们能使用 tcp 选项来只捕获 TCP 数据包,

[root@compute-0-1  ~]# tcpdump -i enp0s3 tcp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
22:36:54.521053 IP 169.144.0.20.ssh > 169.144.0.1.39406: Flags [P.], seq 1433336467:1433336655, ack 3061986618, win 291, options [nop,nop,TS val 83375988 ecr 20883106], length 188
22:36:54.521474 IP 169.144.0.1.39406 > 169.144.0.20.ssh: Flags [.], ack 188, win 9086, options [nop,nop,TS val 20883109 ecr 83375988], length 0
22:36:54.522214 IP 169.144.0.20.ssh > 169.144.0.1.39406: Flags [P.], seq 188:552, ack 1, win 291, options [nop,nop,TS val 83375989 ecr 20883109], length 364
22:36:54.522508 IP 169.144.0.1.39406 > 169.144.0.20.ssh: Flags [.], ack 552, win 9086, options [nop,nop,TS val 20883109 ecr 83375989], length 0
22:36:54.522867 IP 169.144.0.20.ssh > 169.144.0.1.39406: Flags [P.], seq 552:892, ack 1, win 291, options [nop,nop,TS val 83375990 ecr 20883109], length 340
22:36:54.523006 IP 169.144.0.1.39406 > 169.144.0.20.ssh: Flags [.], ack 892, win 9086, options [nop,nop,TS val 20883109 ecr 83375990], length 0
22:36:54.523304 IP 169.144.0.20.ssh > 169.144.0.1.39406: Flags [P.], seq 892:1232, ack 1, win 291, options [nop,nop,TS val 83375990 ecr 20883109], length 340
22:36:54.523461 IP 169.144.0.1.39406 > 169.144.0.20.ssh: Flags [.], ack 1232, win 9086, options [nop,nop,TS val 20883110 ecr 83375990], length 0
22:36:54.523604 IP 169.144.0.20.ssh > 169.144.0.1.39406: Flags [P.], seq 1232:1572, ack 1, win 291, options [nop,nop,TS val 83375991 ecr 20883110], length 340
...................................................................................................................................................

示例:9)从特定接口上的特定端口捕获数据包

使用 tcpdump 命令,我们可以从特定接口 enp0s3 上的特定端口(例如 22)捕获数据包。

语法:

# tcpdump -i {interface-name} port {Port_Number}
[root@compute-0-1  ~]# tcpdump -i enp0s3 port 22
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
22:54:45.032412 IP compute-0-1.example.com.ssh > 169.144.0.1.39406: Flags [P.], seq 1435010787:1435010975, ack 3061993834, win 291, options [nop,nop,TS val 84446499 ecr 21150734], length 188
22:54:45.032631 IP 169.144.0.1.39406 > compute-0-1.example.com.ssh: Flags [.], ack 188, win 9131, options [nop,nop,TS val 21150737 ecr 84446499], length 0
22:54:55.037926 IP compute-0-1.example.com.ssh > 169.144.0.1.39406: Flags [P.], seq 188:576, ack 1, win 291, options [nop,nop,TS val 84456505 ecr 21150737], length 388
22:54:55.038106 IP 169.144.0.1.39406 > compute-0-1.example.com.ssh: Flags [.], ack 576, win 9154, options [nop,nop,TS val 21153238 ecr 84456505], length 0
22:54:55.038286 IP compute-0-1.example.com.ssh > 169.144.0.1.39406: Flags [P.], seq 576:940, ack 1, win 291, options [nop,nop,TS val 84456505 ecr 21153238], length 364
22:54:55.038564 IP 169.144.0.1.39406 > compute-0-1.example.com.ssh: Flags [.], ack 940, win 9177, options [nop,nop,TS val 21153238 ecr 84456505], length 0
22:54:55.038708 IP compute-0-1.example.com.ssh > 169.144.0.1.39406: Flags [P.], seq 940:1304, ack 1, win 291, options [nop,nop,TS val 84456506 ecr 21153238], length 364
............................................................................................................................

示例:10)在特定接口上捕获来自特定来源 IP 的数据包

tcpdump 命令中,使用 src 关键字后跟 IP 地址,我们可以捕获来自特定来源 IP 的数据包,

语法:

# tcpdump -n -i {接口名} src {IP 地址}

例子如下,

[root@compute-0-1  ~]# tcpdump -n -i enp0s3 src 169.144.0.10
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
23:03:45.912733 IP 169.144.0.10.amqp > 169.144.0.20.57800: Flags [.], ack 526623844, win 243, options [nop,nop,TS val 84981008 ecr 84982372], length 0
23:03:46.136757 IP 169.144.0.10.amqp > 169.144.0.20.57796: Flags [.], ack 2535995970, win 252, options [nop,nop,TS val 84981232 ecr 84982596], length 0
23:03:46.153398 IP 169.144.0.10.amqp > 169.144.0.20.57798: Flags [.], ack 3623063621, win 243, options [nop,nop,TS val 84981248 ecr 84982612], length 0
23:03:46.361160 IP 169.144.0.10.amqp > 169.144.0.20.57802: Flags [.], ack 2140263945, win 252, options [nop,nop,TS val 84981456 ecr 84982821], length 0
23:03:46.376926 IP 169.144.0.10.amqp > 169.144.0.20.57808: Flags [.], ack 175946224, win 252, options [nop,nop,TS val 84981472 ecr 84982836], length 0
23:03:46.505242 IP 169.144.0.10.amqp > 169.144.0.20.57810: Flags [.], ack 1016089556, win 252, options [nop,nop,TS val 84981600 ecr 84982965], length 0
23:03:46.616994 IP 169.144.0.10.amqp > 169.144.0.20.57812: Flags [.], ack 832263835, win 252, options [nop,nop,TS val 84981712 ecr 84983076], length 0
23:03:46.809344 IP 169.144.0.10.amqp > 169.144.0.20.57814: Flags [.], ack 2781799939, win 252, options [nop,nop,TS val 84981904 ecr 84983268], length 0
23:03:46.809485 IP 169.144.0.10.amqp > 169.144.0.20.57816: Flags [.], ack 1662816815, win 252, options [nop,nop,TS val 84981904 ecr 84983268], length 0
23:03:47.033301 IP 169.144.0.10.amqp > 169.144.0.20.57818: Flags [.], ack 2387094362, win 252, options [nop,nop,TS val 84982128 ecr 84983492], length 0
^C
10 packets captured
12 packets received by filter
0 packets dropped by kernel

示例:11)在特定接口上捕获来自特定目的 IP 的数据包

语法:

# tcpdump -n -i {接口名} dst {IP 地址}
[root@compute-0-1  ~]# tcpdump -n -i enp0s3 dst 169.144.0.1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
23:10:43.520967 IP 169.144.0.20.ssh > 169.144.0.1.39406: Flags [P.], seq 1439564171:1439564359, ack 3062005550, win 291, options [nop,nop,TS val 85404988 ecr 21390356], length 188
23:10:43.521441 IP 169.144.0.20.ssh > 169.144.0.1.39406: Flags [P.], seq 188:408, ack 1, win 291, options [nop,nop,TS val 85404988 ecr 21390359], length 220
23:10:43.521719 IP 169.144.0.20.ssh > 169.144.0.1.39406: Flags [P.], seq 408:604, ack 1, win 291, options [nop,nop,TS val 85404989 ecr 21390359], length 196
23:10:43.521993 IP 169.144.0.20.ssh > 169.144.0.1.39406: Flags [P.], seq 604:800, ack 1, win 291, options [nop,nop,TS val 85404989 ecr 21390359], length 196
23:10:43.522157 IP 169.144.0.20.ssh > 169.144.0.1.39406: Flags [P.], seq 800:996, ack 1, win 291, options [nop,nop,TS val 85404989 ecr 21390359], length 196
23:10:43.522346 IP 169.144.0.20.ssh > 169.144.0.1.39406: Flags [P.], seq 996:1192, ack 1, win 291, options [nop,nop,TS val 85404989 ecr 21390359], length 196
.........................................................................................

示例:12)捕获两台主机之间的 TCP 数据包通信

假设我想捕获两台主机 169.144.0.1 和 169.144.0.20 之间的 TCP 数据包,示例如下所示,

[root@compute-0-1  ~]# tcpdump -w two-host-tcp-comm.pcap -i enp0s3 tcp and \(host 169.144.0.1 or host 169.144.0.20\)

使用 tcpdump 命令只捕获两台主机之间的 SSH 数据包流,

[root@compute-0-1  ~]# tcpdump -w ssh-comm-two-hosts.pcap -i enp0s3 src 169.144.0.1 and port 22 and dst 169.144.0.20 and port 22

示例:13)捕获两台主机之间(来回)的 UDP 网络数据包

语法:

# tcpdump -w -s -i udp and \(host and host \)
[root@compute-0-1  ~]# tcpdump -w two-host-comm.pcap -s 1000 -i enp0s3 udp and \(host 169.144.0.10 and host 169.144.0.20\)

示例:14)捕获十六进制和 ASCII 格式的数据包

使用 tcpdump 命令,我们可以以 ASCII 和十六进制格式捕获 TCP/IP 数据包,

要使用 -A 选项捕获 ASCII 格式的数据包,示例如下所示:

[root@compute-0-1  ~]# tcpdump -c 10 -A -i enp0s3
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
00:37:10.520060 IP compute-0-1.example.com.ssh > 169.144.0.1.39406: Flags [P.], seq 1452637331:1452637519, ack 3062125586, win 333, options [nop,nop,TS val 90591987 ecr 22687106], length 188
E...[root@compute-0-1 @...............V.|...T....MT......
.fR..Z-....b.:..Z5...{.'p....]."}...Z..9.?......."root@compute-0-1 <.....V..C.....{,...OKP.2.*...`..-sS..1S...........:.O[.....{G..%ze.Pn.T..N.... ....qB..5...n.....`...:=...[..0....k.....S.:..5!.9..G....!-..'..
00:37:10.520319 IP 169.144.0.1.39406 > compute-0-1.example.com.ssh: Flags [.], ack 188, win 13930, options [nop,nop,TS val 22687109 ecr 90591987], length 0
root@compute-0-1 @.|+..............T.V.}O..6j.d.....
.Z-..fR.
00:37:11.687543 IP controller0.example.com.amqp > compute-0-1.example.com.57800: Flags [.], ack 526624548, win 243, options [nop,nop,TS val 90586768 ecr 90588146], length 0
root@compute-0-1 @.!L...
.....(..g....c.$...........
.f>..fC.
00:37:11.687612 IP compute-0-1.example.com.57800 > controller0.example.com.amqp: Flags [.], ack 1, win 237, options [nop,nop,TS val 90593155 ecr 90551716], length 0
root@compute-0-1 @..........
...(.c.$g.......Se.....
.fW..e..
..................................................................................................................................................

要同时以十六进制和 ASCII 格式捕获数据包,请使用 -XX 选项。

[root@compute-0-1  ~]# tcpdump -c 10 -XX -i enp0s3
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
00:39:15.124363 IP compute-0-1.example.com.ssh > 169.144.0.1.39406: Flags [P.], seq 1452640859:1452641047, ack 3062126346, win 333, options [nop,nop,TS val 90716591 ecr 22718257], length 188
0x0000: 0a00 2700 0000 0800 27f4 f935 0800 4510 ..'.....'..5..E.
0x0010: 00f0 5bc6 4000 4006 8afc a990 0014 a990 ..[root@compute-0-1 @.........
0x0020: 0001 0016 99ee 5695 8a5b b684 570a 8018 ......V..[..W...
0x0030: 014d 5418 0000 0101 080a 0568 39af 015a .MT........h9..Z
0x0040: a731 adb7 58b6 1a0f 2006 df67 c9b6 4479 .1..X......g..Dy
0x0050: 19fd 2c3d 2042 3313 35b9 a160 fa87 d42c ..,=.B3.5..`...,
0x0060: 89a9 3d7d dfbf 980d 2596 4f2a 99ba c92a ..=}....%.O*...*
0x0070: 3e1e 7bf7 3af2 a5cc ee4f 10bc 7dfc 630d >.{.:....O..}.c.
0x0080: 898a 0e16 6825 56c7 b683 1de4 3526 ff04 ....h%V.....5&..
0x0090: 68d1 4f7d babd 27ba 84ae c5d3 750b 01bd h.O}..'.....u...
0x00a0: 9c43 e10a 33a6 8df2 a9f0 c052 c7ed 2ff5 .C..3......R../.
0x00b0: bfb1 ce84 edfc c141 6dad fa19 0702 62a7 .......Am.....b.
0x00c0: 306c db6b 2eea 824e eea5 acd7 f92e 6de3 0l.k...N......m.
0x00d0: 85d0 222d f8bf 9051 2c37 93c8 506d 5cb5 .."-...Q,7..Pm\.
0x00e0: 3b4a 2a80 d027 49f2 c996 d2d9 a9eb c1c4 ;J*..'I.........
0x00f0: 7719 c615 8486 d84c e42d 0ba3 698c w......L.-..i.
00:39:15.124648 IP 169.144.0.1.39406 > compute-0-1.example.com.ssh: Flags [.], ack 188, win 13971, options [nop,nop,TS val 22718260 ecr 90716591], length 0
0x0000: 0800 27f4 f935 0a00 2700 0000 0800 4510 ..'..5..'.....E.
0x0010: 0034 6b70 4000 4006 7c0e a990 0001 a990 root@compute-0-1 @.|.......
0x0020: 0014 99ee 0016 b684 570a 5695 8b17 8010 ........W.V.....
0x0030: 3693 7c0e 0000 0101 080a 015a a734 0568 6.|........Z.4.h
0x0040: 39af
.......................................................................

这就是本文的全部内容,我希望您能了解如何使用 tcpdump 命令捕获和分析 TCP/IP 数据包。请分享你的反馈和评论。


via: https://www.linuxtechi.com/capture-analyze-packets-tcpdump-command-linux/

作者:Pradeep Kumar
选题:lujun9972
译者:ypingcn
校对:wxy

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

了解如何验证某人所声称的身份。

上一篇文章中,我们概述了密码学并讨论了密码学的核心概念: 保密性 confidentiality (让数据保密)、 完整性 integrity (防止数据被篡改)和 身份认证 authentication (确认数据源的 身份 identity )。由于要在存在各种身份混乱的现实世界中完成身份认证,人们逐渐建立起一个复杂的 技术生态体系 technological ecosystem ,用于证明某人就是其声称的那个人。在本文中,我们将大致介绍这些体系是如何工作的。

快速回顾公钥密码学及数字签名

互联网世界中的身份认证依赖于公钥密码学,其中密钥分为两部分:拥有者需要保密的私钥和可以对外公开的公钥。经过公钥加密过的数据,只能用对应的私钥解密。举个例子,对于希望与记者建立联系的举报人来说,这个特性非常有用。但就本文介绍的内容而言,私钥更重要的用途是与一个消息一起创建一个 数字签名 digital signature ,用于提供完整性和身份认证。

在实际应用中,我们签名的并不是真实消息,而是经过 密码学哈希函数 cryptographic hash function 处理过的消息 摘要 digest 。要发送一个包含源代码的压缩文件,发送者会对该压缩文件的 256 比特长度的 SHA-256 摘要进行签名,而不是文件本身进行签名,然后用明文发送该压缩包(和签名)。接收者会独立计算收到文件的 SHA-256 摘要,然后结合该摘要、收到的签名及发送者的公钥,使用签名验证算法进行验证。验证过程取决于加密算法,加密算法不同,验证过程也相应不同;而且,很微妙的是签名验证漏洞依然层出不穷。如果签名验证通过,说明文件在传输过程中没有被篡改而且来自于发送者,这是因为只有发送者拥有创建签名所需的私钥。

方案中缺失的环节

上述方案中缺失了一个重要的环节:我们从哪里获得发送者的公钥?发送者可以将公钥与消息一起发送,但除了发送者的自我宣称,我们无法核验其身份。假设你是一名银行柜员,一名顾客走过来向你说,“你好,我是 Jane Doe,我要取一笔钱”。当你要求其证明身份时,她指着衬衫上贴着的姓名标签说道,“看,Jane Doe!”。如果我是这个柜员,我会礼貌的拒绝她的请求。

如果你认识发送者,你们可以私下见面并彼此交换公钥。如果你并不认识发送者,你们可以私下见面,检查对方的证件,确认真实性后接受对方的公钥。为提高流程效率,你可以举办聚会并邀请一堆人,检查他们的证件,然后接受他们的公钥。此外,如果你认识并信任 Jane Doe(尽管她在银行的表现比较反常),Jane 可以参加聚会,收集大家的公钥然后交给你。事实上,Jane 可以使用她自己的私钥对这些公钥(及对应的身份信息)进行签名,进而你可以从一个线上密钥库)获取公钥(及对应的身份信息)并信任已被 Jane 签名的那部分。如果一个人的公钥被很多你信任的人(即使你并不认识他们)签名,你也可能选择信任这个人。按照这种方式,你可以建立一个 信任网络 Web of Trust

但事情也变得更加复杂:我们需要建立一种标准的编码机制,可以将公钥和其对应的身份信息编码成一个 数字捆绑 digital bundle ,以便我们进一步进行签名。更准确的说,这类数字捆绑被称为 证书 cerificate 。我们还需要可以创建、使用和管理这些证书的工具链。满足诸如此类的各种需求的方案构成了 公钥基础设施 public key infrastructure (PKI)。

比信任网络更进一步

你可以用人际关系网类比信任网络。如果人们之间广泛互信,可以很容易找到(两个人之间的)一条 短信任链 short path of trust :就像一个社交圈。基于 GPG 加密的邮件依赖于信任网络,(理论上)只适用于与少量朋友、家庭或同事进行联系的情形。

(LCTT 译注:作者提到的“短信任链”应该是暗示“六度空间理论”,即任意两个陌生人之间所间隔的人一般不会超过 6 个。对 GPG 的唱衰,一方面是因为密钥管理的复杂性没有改善,另一方面 Yahoo 和 Google 都提出了更便利的端到端加密方案。)

在实际应用中,信任网络有一些“ 硬伤 significant problems ”,主要是在可扩展性方面。当网络规模逐渐增大或者人们之间的连接较少时,信任网络就会慢慢失效。如果信任链逐渐变长,信任链中某人有意或无意误签证书的几率也会逐渐增大。如果信任链不存在,你不得不自己创建一条信任链,与其它组织建立联系,验证它们的密钥以符合你的要求。考虑下面的场景,你和你的朋友要访问一个从未使用过的在线商店。你首先需要核验网站所用的公钥属于其对应的公司而不是伪造者,进而建立安全通信信道,最后完成下订单操作。核验公钥的方法包括去实体店、打电话等,都比较麻烦。这样会导致在线购物变得不那么便利(或者说不那么安全,毕竟很多人会图省事,不去核验密钥)。

如果世界上有那么几个格外值得信任的人,他们专门负责核验和签发网站证书,情况会怎样呢?你可以只信任他们,那么浏览互联网也会变得更加容易。整体来看,这就是当今互联网的工作方式。那些“格外值得信任的人”就是被称为 证书颁发机构 cerificate authoritie (CA)的公司。当网站希望获得公钥签名时,只需向 CA 提交 证书签名请求 certificate signing request (CSR)。

CSR 类似于包括公钥和身份信息(在本例中,即服务器的主机名)的 存根 stub 证书,但 CA 并不会直接对 CSR 本身进行签名。CA 在签名之前会进行一些验证。对于一些证书类型(LCTT 译注: 域名证实 Domain Validated (DV) 类型),CA 只验证申请者的确是 CSR 中列出主机名对应域名的控制者(例如通过邮件验证,让申请者完成指定的域名解析)。对于另一些证书类型 (LCTT 译注:链接中提到 扩展证实 Extended Validated (EV)类型,其实还有 OV Organization Validated 类型),CA 还会检查相关法律文书,例如公司营业执照等。一旦验证完成,CA(一般在申请者付费后)会从 CSR 中取出数据(即公钥和身份信息),使用 CA 自己的私钥进行签名,创建一个(签名)证书并发送给申请者。申请者将该证书部署在网站服务器上,当用户使用 HTTPS (或其它基于 TLS 加密的协议)与服务器通信时,该证书被分发给用户。

当用户访问该网站时,浏览器获取该证书,接着检查证书中的主机名是否与当前正在连接的网站一致(下文会详细说明),核验 CA 签名有效性。如果其中一步验证不通过,浏览器会给出安全警告并切断与网站的连接。反之,如果验证通过,浏览器会使用证书中的公钥来核验该服务器发送的签名信息,确认该服务器持有该证书的私钥。有几种算法用于协商后续通信用到的 共享密钥 shared secret key ,其中一种也用到了服务器发送的签名信息。 密钥交换 key exchange 算法不在本文的讨论范围,可以参考这个视频,其中仔细说明了一种密钥交换算法。

建立信任

你可能会问,“如果 CA 使用其私钥对证书进行签名,也就意味着我们需要使用 CA 的公钥验证证书。那么 CA 的公钥从何而来,谁对其进行签名呢?” 答案是 CA 对自己签名!可以使用证书公钥对应的私钥,对证书本身进行签名!这类签名证书被称为是 自签名的 self-signed ;在 PKI 体系下,这意味着对你说“相信我”。(为了表达方便,人们通常说用证书进行了签名,虽然真正用于签名的私钥并不在证书中。)

通过遵守浏览器操作系统供应商建立的规则,CA 表明自己足够可靠并寻求加入到浏览器或操作系统预装的一组自签名证书中。这些证书被称为“ 信任锚 trust anchor ”或 CA 根证书 root CA certificate ,被存储在根证书区,我们 约定 implicitly 信任该区域内的证书。

CA 也可以签发一种特殊的证书,该证书自身可以作为 CA。在这种情况下,它们可以生成一个证书链。要核验证书链,需要从“信任锚”(也就是 CA 根证书)开始,使用当前证书的公钥核验下一层证书的签名(或其它一些信息)。按照这个方式依次核验下一层证书,直到证书链底部。如果整个核验过程没有问题,信任链也建立完成。当向 CA 付费为网站签发证书时,实际购买的是将证书放置在证书链下的权利。CA 将卖出的证书标记为“不可签发子证书”,这样它们可以在适当的长度终止信任链(防止其继续向下扩展)。

为何要使用长度超过 2 的信任链呢?毕竟网站的证书可以直接被 CA 根证书签名。在实际应用中,很多因素促使 CA 创建 中间 CA 证书 intermediate CA certificate ,最主要是为了方便。由于价值连城,CA 根证书对应的私钥通常被存放在特定的设备中,一种需要多人解锁的 硬件安全模块 hardware security module (HSM),该模块完全离线并被保管在配备监控和报警设备的地下室中。

CA/浏览器论坛 CAB Forum, CA/Browser Forum 负责管理 CA,要求任何与 CA 根证书(LCTT 译注:就像前文提到的那样,这里是指对应的私钥)相关的操作必须由人工完成。设想一下,如果每个证书请求都需要员工将请求内容拷贝到保密介质中、进入地下室、与同事一起解锁 HSM、(使用 CA 根证书对应的私钥)签名证书,最后将签名证书从保密介质中拷贝出来;那么每天为大量网站签发证书是相当繁重乏味的工作。因此,CA 创建内部使用的中间 CA,用于证书签发自动化。

如果想查看证书链,可以在 Firefox 中点击地址栏的锁型图标,接着打开页面信息,然后点击“安全”面板中的“查看证书”按钮。在本文写作时,opensource.com 使用的证书链如下:

DigiCert High Assurance EV Root CA
    DigiCert SHA2 High Assurance Server CA
        opensource.com

中间人

我之前提到,浏览器需要核验证书中的主机名与已经建立连接的主机名一致。为什么需要这一步呢?要回答这个问题,需要了解所谓的 中间人攻击 man-in-the-middle, MIMT 。有一类网络攻击可以让攻击者将自己置身于客户端和服务端中间,冒充客户端与服务端连接,同时冒充服务端与客户端连接。如果网络流量是通过 HTTPS 传输的,加密的流量无法被窃听。此时,攻击者会创建一个代理,接收来自受害者的 HTTPS 连接,解密信息后构建一个新的 HTTPS 连接到原始目的地(即服务端)。为了建立假冒的 HTTPS 连接,代理必须返回一个攻击者具有对应私钥的证书。攻击者可以生成自签名证书,但受害者的浏览器并不会信任该证书,因为它并不是根证书库中的 CA 根证书签发的。换一个方法,攻击者使用一个受信任 CA 签发但主机名对应其自有域名的证书,结果会怎样呢?

再回到银行的那个例子,我们是银行柜员,一位男性顾客进入银行要求从 Jane Doe 的账户上取钱。当被要求提供身份证明时,他给出了 Joe Smith 的有效驾驶执照。如果这个交易可以完成,我们无疑会被银行开除。类似的,如果检测到证书中的主机名与连接对应的主机名不一致,浏览器会给出类似“连接不安全”的警告和查看更多内容的选项。在 Firefox 中,这类错误被标记为 SSL_ERROR_BAD_CERT_DOMAIN

我希望你阅读完本文起码记住这一点:如果看到这类警告,不要无视它们!它们出现意味着,或者该网站配置存在严重问题(不推荐访问),或者你已经是中间人攻击的潜在受害者。

总结

虽然本文只触及了 PKI 世界的一些皮毛,我希望我已经为你展示了便于后续探索的大致蓝图。密码学和 PKI 是美与复杂性的结合体。越深入研究,越能发现更多的美和复杂性,就像分形那样。


via: https://opensource.com/article/18/7/private-keys

作者:Alex Wood 选题:lujun9972 译者:pinewall 校对:wxy

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

了解 Hugo 如何使构建网站变得有趣。

你是不是强烈地想搭建博客来将自己对软件框架等的探索学习成果分享呢?你是不是面对缺乏指导文档而一团糟的项目就有一种想去改变它的冲动呢?或者换个角度,你是不是十分期待能创建一个属于自己的个人博客网站呢?

很多人在想搭建博客之前都有一些严重的迟疑顾虑:感觉自己缺乏内容管理系统(CMS)的相关知识,更缺乏时间去学习这些知识。现在,如果我说不用花费大把的时间去学习 CMS 系统、学习如何创建一个静态网站、更不用操心如何去强化网站以防止它受到黑客攻击的问题,你就可以在 30 分钟之内创建一个博客?你信不信?利用 Hugo 工具,就可以实现这一切。

Hugo 是一个基于 Go 语言开发的静态站点生成工具。也许你会问,为什么选择它?

  • 无需数据库、无需需要各种权限的插件、无需跑在服务器上的底层平台,更没有额外的安全问题。
  • 都是静态站点,因此拥有轻量级、快速响应的服务性能。此外,所有的网页都是在部署的时候生成,所以服务器负载很小。
  • 极易操作的版本控制。一些 CMS 平台使用它们自己的版本控制软件(VCS)或者在网页上集成 Git 工具。而 Hugo,所有的源文件都可以用你所选的 VCS 软件来管理。

0-5 分钟:下载 Hugo,生成一个网站

直白的说,Hugo 使得写一个网站又一次变得有趣起来。让我们来个 30 分钟计时,搭建一个网站。

为了简化 Hugo 安装流程,这里直接使用 Hugo 可执行安装文件。

  1. 下载和你操作系统匹配的 Hugo 版本
  2. 压缩包解压到指定路径,例如 windows 系统的 C:\hugo_dir 或者 Linux 系统的 ~/hugo_dir 目录;下文中的变量 ${HUGO_HOME} 所指的路径就是这个安装目录;
  3. 打开命令行终端,进入安装目录:cd ${HUGO_HOME}
  4. 确认 Hugo 已经启动:
* Unix 系统:`${HUGO_HOME}/[hugo version]`;
* Windows 系统:`${HUGO_HOME}\[hugo.exe version]`,例如:cmd 命令行中输入:`c:\hugo_dir\hugo version`。为了书写上的简化,下文中的 `hugo` 就是指 hugo 可执行文件所在的路径(包括可执行文件),例如命令 `hugo version` 就是指命令 `c:\hugo_dir\hugo version` 。(LCTT 译注:可以把 hugo 可执行文件所在的路径添加到系统环境变量下,这样就可以直接在终端中输入 `hugo version`)

如果命令 hugo version 报错,你可能下载了错误的版本。当然,有很多种方法安装 Hugo,更多详细信息请查阅 官方文档。最稳妥的方法就是把 Hugo 可执行文件放在某个路径下,然后执行的时候带上路径名

  1. 创建一个新的站点来作为你的博客,输入命令:hugo new site awesome-blog
  2. 进入新创建的路径下: cd awesome-blog

恭喜你!你已经创建了自己的新博客。

5-10 分钟:为博客设置主题

Hugo 中你可以自己构建博客的主题或者使用网上已经有的一些主题。这里选择 Kiera 主题,因为它简洁漂亮。按以下步骤来安装该主题:

  1. 进入主题所在目录:cd themes
  2. 克隆主题:git clone https://github.com/avianto/hugo-kiera kiera。如果你没有安装 Git 工具:

    • Github 上下载 hugo 的 .zip 格式的文件;
    • 解压该 .zip 文件到你的博客主题 theme 路径;
    • 重命名 hugo-kiera-masterkiera
  3. 返回博客主路径:cd awesome-blog
  4. 激活主题;通常来说,主题(包括 Kiera)都自带文件夹 exampleSite,里面存放了内容配置的示例文件。激活 Kiera 主题需要拷贝它提供的 config.toml 到你的博客下:
* Unix 系统:`cp themes/kiera/exampleSite/config.toml .`;
* Windows 系统:`copy themes\kiera\exampleSite\config.toml .`;
* 选择 `Yes` 来覆盖原有的 `config.toml`;
  1. ( 可选操作 )你可以选择可视化的方式启动服务器来验证主题是否生效:hugo server -D 然后在浏览器中输入 http://localhost:1313。可用通过在终端中输入 Crtl+C 来停止服务器运行。现在你的博客还是空的,但这也给你留了写作的空间。它看起来如下所示:

你已经成功的给博客设置了主题!你可以在官方 Hugo 主题 网站上找到上百种漂亮的主题供你使用。

10-20 分钟:给博客添加内容

对于碗来说,它是空的时候用处最大,可以用来盛放东西;但对于博客来说不是这样,空博客几乎毫无用处。在这一步,你将会给博客添加内容。Hugo 和 Kiera 主题都为这个工作提供了方便性。按以下步骤来进行你的第一次提交:

  1. archetypes 将会是你的内容模板。
  2. 添加主题中的 archtypes 至你的博客:
* Unix 系统: `cp themes/kiera/archetypes/* archetypes/`
* Windows 系统:`copy themes\kiera\archetypes\* archetypes\`
* 选择 `Yes` 来覆盖原来的 `default.md` 内容架构类型
  1. 创建博客 posts 目录:
* Unix 系统: `mkdir content/posts`
* Windows 系统: `mkdir content\posts`
  1. 利用 Hugo 生成你的 post:
* Unix 系统:`hugo nes posts/first-post.md`;
* Windows 系统:`hugo new posts\first-post.md`;
  1. 在文本编辑器中打开这个新建的 post 文件:
* Unix 系统:`gedit content/posts/first-post.md`;
* Windows 系统:`notepadd content\posts\first-post.md`;

此刻,你可以疯狂起来了。注意到你的提交文件中包括两个部分。第一部分是以 +++ 符号分隔开的。它包括了提交文档的主要数据,例如名称、时间等。在 Hugo 中,这叫做前缀。在前缀之后,才是正文。下面编辑第一个提交文件内容:

+++
title = "First Post"
date = 2018-03-03T13:23:10+01:00
draft = false
tags = ["Getting started"]
categories = []
+++

Hello Hugo world! No more excuses for having no blog or documentation now!

现在你要做的就是启动你的服务器:hugo server -D;然后打开浏览器,输入 http://localhost:1313/

20-30 分钟:调整网站

前面的工作很完美,但还有一些问题需要解决。例如,简单地命名你的站点:

  1. 终端中按下 Ctrl+C 以停止服务器。
  2. 打开 config.toml,编辑博客的名称,版权,你的姓名,社交网站等等。

当你再次启动服务器后,你会发现博客私人订制味道更浓了。不过,还少一个重要的基础内容:主菜单。快速的解决这个问题。返回 config.toml 文件,在末尾插入如下一段:

[[menu.main]]
    name = "Home" #Name in the navigation bar
    weight = 10 #The larger the weight, the more on the right this item will be
    url = "/" #URL address
[[menu.main]]
    name = "Posts"
    weight = 20
    url = "/posts/"

上面这段代码添加了 HomePosts 到主菜单中。你还需要一个 About 页面。这次是创建一个 .md 文件,而不是编辑 config.toml 文件:

  1. 创建 about.md 文件:hugo new about.md 。注意它是 about.md,不是 posts/about.md。该页面不是博客提交内容,所以你不想它显示到博客内容提交当中吧。
  2. 用文本编辑器打开该文件,输入如下一段:
+++
title = "About"
date = 2018-03-03T13:50:49+01:00
menu = "main" #Display this page on the nav menu
weight = "30" #Right-most nav item
meta = "false" #Do not display tags or categories
+++

> Waves are the practice of the water. Shunryu Suzuki

当你启动你的服务器并输入:http://localhost:1313/,你将会看到你的博客。(访问我 Gihub 主页上的 例子 )如果你想让文章的菜单栏和 Github 相似,给 themes/kiera/static/css/styles.css 打上这个 补丁


via: https://opensource.com/article/18/3/start-blog-30-minutes-hugo

作者:Marek Czernek 
译者:jrg 
校对:wxy

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

zsh 提供了数之不尽的功能和特性,这里有五个可以让你在命令行效率暴增的方法。

Z shell(zsh)是 Linux 和类 Unix 系统中的一个命令解析器)。 它跟 sh (Bourne shell) 家族的其它解析器(如 bash 和 ksh)有着相似的特点,但它还提供了大量的高级特性以及强大的命令行编辑功能,如增强版 Tab 补全。

在这里不可能涉及到 zsh 的所有功能,描述它的特性需要好几百页。在本文中,我会列出 5 个技巧,让你通过在命令行使用 zsh 来提高你的生产力。

1、主题和插件

多年来,开源社区已经为 zsh 开发了数不清的主题和插件。主题是一个预定义提示符的配置,而插件则是一组常用的别名命令和函数,可以让你更方便的使用一种特定的命令或者编程语言。

如果你现在想开始用 zsh 的主题和插件,那么使用一种 zsh 的配置框架是你最快的入门方式。在众多的配置框架中,最受欢迎的则是 Oh My Zsh。在默认配置中,它就已经为 zsh 启用了一些合理的配置,同时它也自带上百个主题和插件。

主题会在你的命令行提示符之前添加一些有用的信息,比如你 Git 仓库的状态,或者是当前使用的 Python 虚拟环境,所以它会让你的工作更高效。只需要看到这些信息,你就不用再敲命令去重新获取它们,而且这些提示也相当酷炫。下图就是我选用的主题 Powerlevel9k

 title=

zsh 主题 Powerlevel9k

除了主题,Oh my Zsh 还自带了大量常用的 zsh 插件。比如,通过启用 Git 插件,你可以用一组简便的命令别名操作 Git, 比如

$ alias | grep -i git | sort -R | head -10
g=git
ga='git add'
gapa='git add --patch'
gap='git apply'
gdt='git diff-tree --no-commit-id --name-only -r'
gau='git add --update'
gstp='git stash pop'
gbda='git branch --no-color --merged | command grep -vE "^(\*|\s*(master|develop|dev)\s*$)" | command xargs -n 1 git branch -d'
gcs='git commit -S'
glg='git log --stat'

zsh 还有许多插件可以用于许多编程语言、打包系统和一些平时在命令行中常用的工具。以下是我 Ferdora 工作站中用到的插件表:

git golang fedora docker oc sudo vi-mode virtualenvwrapper

2、智能的命令别名

命令别名在 zsh 中十分有用。为你常用的命令定义别名可以节省你的打字时间。Oh My Zsh 默认配置了一些常用的命令别名,包括目录导航命令别名,为常用的命令添加额外的选项,比如:

ls='ls --color=tty'
grep='grep  --color=auto --exclude-dir={.bzr,CVS,.git,.hg,.svn}'

除了命令别名以外, zsh 还自带两种额外常用的别名类型:后缀别名和全局别名。

后缀别名可以让你基于文件后缀,在命令行中利用指定程序打开这个文件。比如,要用 vim 打开 YAML 文件,可以定义以下命令行别名:

alias -s {yml,yaml}=vim

现在,如果你在命令行中输入任何后缀名为 ymlyaml 文件, zsh 都会用 vim 打开这个文件。

$ playbook.yml
# Opens file playbook.yml using vim

全局别名可以让你创建一个可在命令行的任何地方展开的别名,而不仅仅是在命令开始的时候。这个在你想替换常用文件名或者管道命令的时候就显得非常有用了。比如:

alias -g G='| grep -i'

要使用这个别名,只要你在想用管道命令的时候输入 G 就好了:

$ ls -l G do
drwxr-xr-x.  5 rgerardi rgerardi 4096 Aug  7 14:08 Documents
drwxr-xr-x.  6 rgerardi rgerardi 4096 Aug 24 14:51 Downloads

接着,我们就来看看 zsh 是如何导航文件系统的。

3、便捷的目录导航

当你使用命令行的时候,在不同的目录之间切换访问是最常见的工作了。 zsh 提供了一些十分有用的目录导航功能来简化这个操作。这些功能已经集成到 Oh My Zsh 中了, 而你可以用以下命令来启用它

setopt  autocd autopushd \ pushdignoredups

使用了上面的配置后,你就不用输入 cd 来切换目录了,只需要输入目录名称,zsh 就会自动切换到这个目录中:

$ pwd
/home/rgerardi
$ /tmp
$ pwd
/tmp

如果想要回退,只要输入 -:

zsh 会记录你访问过的目录,这样下次你就可以快速切换到这些目录中。如果想要看这个目录列表,只要输入 dirs -v

$ dirs -v
0       ~
1       /var/log
2       /var/opt
3       /usr/bin
4       /usr/local
5       /usr/lib
6       /tmp
7       ~/Projects/Opensource.com/zsh-5tips
8       ~/Projects
9       ~/Projects/ansible
10      ~/Documents

如果想要切换到这个列表中的其中一个目录,只需输入 ~## 代表目录在列表中的序号)就可以了。比如

$ pwd
/home/rgerardi
$ ~4
$ pwd
/usr/local

你甚至可以用别名组合这些命令,这样切换起来就变得更简单:

d='dirs -v | head -10'
1='cd -'
2='cd -2'
3='cd -3'
4='cd -4'
5='cd -5'
6='cd -6'
7='cd -7'
8='cd -8'
9='cd -9'

现在你可以通过输入 d 来查看这个目录列表的前10个,然后用目录的序号来进行切换:

$ d
0       /usr/local
1       ~
2       /var/log
3       /var/opt
4       /usr/bin
5       /usr/lib
6       /tmp
7       ~/Projects/Opensource.com/zsh-5tips
8       ~/Projects
9       ~/Projects/ansible
$ pwd
/usr/local
$ 6
/tmp
$ pwd
/tmp

最后,你可以在 zsh 中利用 Tab 来自动补全目录名称。你可以先输入目录的首字母,然后按 TAB 键来补全它们:

$ pwd
/home/rgerardi
$ p/o/z (TAB)
$ Projects/Opensource.com/zsh-5tips/

以上仅仅是 zsh 强大的 Tab 补全系统中的一个功能。接来下我们来探索它更多的功能。

4、先进的 Tab 补全

zsh 强大的补全系统是它的卖点之一。为了简便起见,我称它为 Tab 补全,然而在系统底层,它起到了几个作用。这里通常包括展开以及命令补全,我会在这里用讨论它们。如果想了解更多,详见 用户手册

在 Oh My Zsh 中,命令补全是默认启用的。要启用它,你只要在 .zshrc 文件中添加以下命令:

autoload -U compinit
compinit

zsh 的补全系统非常智能。它会尝试唯一提示可用在当前上下文环境中的项目 —— 比如,你输入了 cdTAB,zsh 只会为你提示目录名,因为它知道其它的项目放在 cd 后面没用。

反之,如果你使用与用户相关的命令便会提示用户名,而 ssh 或者 ping 这类则会提示主机名。

zsh 拥有一个巨大而又完整的库,因此它能识别许多不同的命令。比如,如果你使用 tar 命令, 你可以按 TAB 键,它会为你展示一个可以用于解压的文件列表:

$ tar -xzvf test1.tar.gz test1/file1 (TAB)
file1 file2

如果使用 git 的话,这里有个更高级的示例。在这个示例中,当你按 TAB 键, zsh 会自动补全当前库可以操作的文件:

$ ls
original  plan.txt  zsh-5tips.md  zsh_theme_small.png
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   zsh-5tips.md

no changes added to commit (use "git add" and/or "git commit -a")
$ git add (TAB)
$ git add zsh-5tips.md

zsh 还能识别命令行选项,同时它只会提示与选中子命令相关的命令列表:

$ git commit - (TAB)
--all                  -a       -- stage all modified and deleted paths
--allow-empty                   -- allow recording an empty commit
--allow-empty-message           -- allow recording a commit with an empty message
--amend                         -- amend the tip of the current branch
--author                        -- override the author name used in the commit
--branch                        -- show branch information
--cleanup                       -- specify how the commit message should be cleaned up
--date                          -- override the author date used in the commit
--dry-run                       -- only show the list of paths that are to be committed or not, and any untracked
--edit                 -e       -- edit the commit message before committing
--file                 -F       -- read commit message from given file
--gpg-sign             -S       -- GPG-sign the commit
--include              -i       -- update the given files and commit the whole index
--interactive                   -- interactively update paths in the index file
--message              -m       -- use the given message as the commit message
... TRUNCATED ...

在按 TAB 键之后,你可以使用方向键来选择你想用的命令。现在你就不用记住所有的 git 命令项了。

zsh 还有很多有用的功能。当你用它的时候,你就知道哪些对你才是最有用的。

5、命令行编辑与历史记录

zsh 的命令行编辑功能也十分有用。默认条件下,它是模拟 emacs 编辑器的。如果你是跟我一样更喜欢用 vi/vim,你可以用以下命令启用 vi 的键绑定。

$ bindkey -v

如果你使用 Oh My Zsh,vi-mode 插件可以启用额外的绑定,同时会在你的命令提示符上增加 vi 的模式提示 —— 这个非常有用。

当启用 vi 的绑定后,你可以在命令行中使用 vi 命令进行编辑。比如,输入 ESC+/ 来查找命令行记录。在查找的时候,输入 n 来找下一个匹配行,输入 N 来找上一个。输入 ESC 后,常用的 vi 命令都可以使用,如输入 0 跳转到行首,输入 $ 跳转到行尾,输入 i 来插入文本,输入 a 来追加文本等等,即使是跟随的命令也同样有效,比如输入 cw 来修改单词。

除了命令行编辑,如果你想修改或重新执行之前使用过的命令,zsh 还提供几个常用的命令行历史功能。比如,你打错了一个命令,输入 fc,你可以在你偏好的编辑器中修复最后一条命令。使用哪个编辑是参照 $EDITOR 变量的,而默认是使用 vi。

另外一个有用的命令是 r, 它会重新执行上一条命令;而 r <WORD> 则会执行上一条包含 WORD 的命令。

最后,输入两个感叹号(!!),可以在命令行中回溯最后一条命令。这个十分有用,比如,当你忘记使用 sudo 去执行需要权限的命令时:

$ less /var/log/dnf.log
/var/log/dnf.log: Permission denied
$ sudo !!
$ sudo less /var/log/dnf.log

这个功能让查找并且重新执行之前命令的操作更加方便。

下一步呢?

这里仅仅介绍了几个可以让你提高生产率的 zsh 特性;其实还有更多功能有待你的发掘;想知道更多的信息,你可以访问以下的资源:

你有使用 zsh 提高生产力的技巧可以分享吗?我很乐意在下方评论中看到它们。


via: https://opensource.com/article/18/9/tips-productivity-zsh

作者:Ricardo Gerardi 选题:lujun9972 译者:tnuoccalanosrep 校对:wxy

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

创建照片幻灯片只需点击几下。以下是如何在 Ubuntu 18.04 和其他 Linux 发行版中制作照片幻灯片。

How to create slideshow of photos in Ubuntu Linux

想象一下,你的朋友和亲戚正在拜访你,并请你展示最近的活动/旅行照片。

你将照片保存在计算机上,并整齐地放在单独的文件夹中。你邀请计算机附近的所有人。你进入该文件夹​​,单击其中一张图片,然后按箭头键逐个显示照片。

但那太累了!如果这些图片每隔几秒自动更改一次,那将会好很多。

这称之为幻灯片,我将向你展示如何在 Ubuntu 中创建照片幻灯片。这能让你在文件夹中循环播放图片并以全屏模式显示它们。

在 Ubuntu 18.04 和其他 Linux 发行版中创建照片幻灯片

虽然有几种图像浏览器可以做到,但我将向你展示大多数发行版中应该提供的两种最常用的工具。

方法 1:使用 GNOME 默认图像浏览器浏览照片幻灯片

如果你在 Ubuntu 18.04 或任何其他发行版中使用 GNOME,那么你很幸运。Gnome 的默认图像浏览器,Eye of GNOME,能够在当前文件夹中显示图片的幻灯片。

只需单击其中一张图片,你将在程序的右上角菜单中看到设置选项。它看起来像堆叠在一起的三条横栏。

你会在这里看到几个选项。勾选幻灯片选项,它将全屏显示图像。

How to create slideshow of photos in Ubuntu Linux

默认情况下,图像以 5 秒的间隔变化。你可以进入 “Preferences -> Slideshow” 来更改幻灯片放映间隔。

change slideshow interval in Ubuntu

方法 2:使用 Shotwell Photo Manager 进行照片幻灯片放映

Shotwell 是一款流行的 Linux 照片管理程序。适用于所有主要的 Linux 发行版。

如果尚未安装,请在你的发行版软件中心中搜索 Shotwell 并安装。

Shotwell 的运行略有不同。如果你在 Shotwell Viewer 中直接打开照片,则不会看到首选项或者幻灯片的选项。

对于幻灯片放映和其他选项,你必须打开 Shotwell 并导入包含这些图片的文件夹。导入文件夹后,从左侧窗格中选择该文件夹,然后单击菜单中的 “View”。你应该在此处看到幻灯片选项。只需单击它即可创建所选文件夹中所有图像的幻灯片。

How to create slideshow of photos in Ubuntu Linux

你还可以更改幻灯片设置。当图像以全屏显示时,将显示此选项。只需将鼠标悬停在底部,你就会看到一个设置选项。

创建照片幻灯片很容易

如你所见,在 Linux 中创建照片幻灯片非常简单。我希望你觉得这个简单的提示有用。如果你有任何问题或建议,请在下面的评论栏告诉我们。


via: https://itsfoss.com/photo-slideshow-ubuntu/

作者:Abhishek Prakash 选题:lujun9972 译者:geekpi 校对:wxy

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