Merge remote-tracking branch 'LCTT/master'

This commit is contained in:
Xingyu Wang 2020-07-12 11:16:51 +08:00
commit 7ff3669a37
5 changed files with 467 additions and 482 deletions

View File

@ -0,0 +1,315 @@
[#]: collector: (lujun9972)
[#]: translator: (wxy)
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-12407-1.html)
[#]: subject: (Add nodes to your private cloud using Cloud-init)
[#]: via: (https://opensource.com/article/20/5/create-simple-cloud-init-service-your-homelab)
[#]: author: (Chris Collins https://opensource.com/users/clcollins)
使用 Cloud-init 将节点添加到你的私有云中
======
> 像主流云提供商的处理方式一样,在家中添加机器到你的私有云。
![](https://img.linux.net.cn/data/attachment/album/202007/12/100823rj096h3ax4hhehey.jpg)
[Cloud-init][2] 是一种广泛使用的行业标准方法,用于初始化云实例。云提供商使用 Cloud-init 来定制实例的网络配置、实例信息,甚至用户提供的配置指令。它也是一个可以在你的“家庭私有云”中使用的很好的工具,可以为你的家庭实验室的虚拟机和物理机的初始设置和配置添加一点自动化 —— 并了解更多关于大型云提供商是如何工作的信息。关于更多的细节和背景,请看我之前的文章《[在你的树莓派家庭实验室中使用 Cloud-init][3]》。
![A screen showing the boot process for a Linux server running Cloud-init ][4]
*运行 Cloud-init 的 Linux 服务器的启动过程Chris Collins[CC BY-SA 4.0][5]*
诚然Cloud-init 对于为许多不同客户配置机器的云提供商来说,比对于由单个系统管理员运行的家庭实验室更有用,而且 Cloud-init 解决的许多问题对于家庭实验室来说可能有点多余。然而,设置它并了解它的工作原理是了解更多关于这种云技术的好方法,更不用说它是首次启动时配置设备的好方法。
本教程使用 Cloud-init 的 NoCloud 数据源,它允许 Cloud-init 在传统的云提供商环境之外使用。本文将向你展示如何在客户端设备上安装 Cloud-init并设置一个运行 Web 服务的容器来响应客户端的请求。你还将学习如何审查客户端从 Web 服务中请求的内容,并修改 Web 服务的容器,以提供基本的、静态的 Cloud-init 服务。
### 在现有系统上设置 Cloud-init
Cloud-init 可能在新系统首次启动时最有用,它可以查询配置数据,并根据指令对系统进行定制。它可以[包含在树莓派和单板计算机的磁盘镜像中][6],也可以添加到用于<ruby>配给<rt>provision</rt></ruby>虚拟机的镜像中。对于测试用途来说,无论是在现有系统上安装并运行 Cloud-init还是安装一个新系统然后设置 Cloud-init都是很容易的。
作为大多数云提供商使用的主要服务,大多数 Linux 发行版都支持 Cloud-init。在这个例子中我将使用 Fedora 31 Server 来安装树莓派,但在 Raspbian、Ubuntu、CentOS 和大多数其他发行版上也可以用同样的方式来完成。
#### 安装并启用云计算初始服务
在你想作为 Cloud-init 客户端的系统上,安装 Cloud-init 包。如果你使用的是 Fedora
```
# Install the cloud-init package
dnf install -y cloud-init
```
Cloud-init 实际上是四个不同的服务(至少在 systemd 下是这样),这些服务负责检索配置数据,并在启动过程的不同阶段进行配置更改,这使得可以做的事情更加灵活。虽然你不太可能直接与这些服务进行太多交互,但在你需要排除一些故障时,知道它们是什么还是很有用的。它们是:
* cloud-init-local.service
* cloud-init.service
* cloud-config.service
* cloud-final.service
启用所有四个服务:
```
# Enable the four cloud-init services
systemctl enable cloud-init-local.service
systemctl enable cloud-init.service
systemctl enable cloud-config.service
systemctl enable cloud-final.service
```
#### 配置数据源以查询
启用服务后,请配置数据源,客户端将从该数据源查询配置数据。有[许多数据源类型][7],而且大多数都是为特定的云提供商配置的。对于你的家庭实验室,请使用 NoCloud 数据源,(如上所述)它是为在没有云提供商的情况下使用 Cloud-init 而设计的。
NoCloud 允许以多种方式包含配置信息:以内核参数中的键/值对,用于在启动时挂载的 CD或虚拟机中的虚拟 CD包含在文件系统中的文件中或者像本例中一样通过 HTTP 从指定的 URL“NoCloud Net” 选项)获取配置信息。
数据源配置可以通过内核参数提供,也可以在 Cloud-init 配置文件 `/etc/cloud/cloud.cfg` 中进行设置。该配置文件对于使用自定义磁盘镜像设置 Cloud-init 或在现有主机上进行测试非常方便。
Cloud-init 还会合并在 `/etc/cloud/cloud.cfg.d/` 中找到的任何 `*.cfg` 文件中的配置数据,因此为了保持整洁,请在 `/etc/cloud/cloud.cfg.d/10_datasource.cfg` 中配置数据源。Cloud-init 可以通过使用以下语法从 `seedfrom` 键指向的 HTTP 数据源中读取数据。
```
seedfrom: http://ip_address:port/
```
IP 地址和端口是你将在本文后面创建的 Web 服务。我使用了我的笔记本电脑的 IP 和 8080 端口。这也可以是 DNS 名称。
创建 `/etc/cloud/cloud.cfg.d/10_datasource.cfg` 文件:
```
# Add the datasource:
# /etc/cloud/cloud.cfg.d/10_datasource.cfg
# NOTE THE TRAILING SLASH HERE!
datasource:
  NoCloud:
    seedfrom: http://ip_address:port/
```
客户端设置就是这样。现在,重新启动客户端后,它将尝试从你在 `seedfrom` 键中输入的 URL 检索配置数据,并进行必要的任何配置更改。
下一步是设置一个 Web 服务器来侦听客户端请求,以便你确定需要提供的服务。
### 设置网络服务器以审查客户请求
你可以使用 [Podman][8] 或其他容器编排工具(如 Docker 或 Kubernetes快速创建和运行 Web 服务器。这个例子使用的是 Podman但同样的命令也适用于 Docker。
要开始,请使用 `fedora:31` 容器镜像并创建一个容器文件(对于 Docker 来说,这会是一个 Dockerfile来安装和配置 Nginx。从该容器文件中你可以构建一个自定义镜像并在你希望提供 Cloud-init 服务的主机上运行它。
创建一个包含以下内容的容器文件:
```
FROM fedora:31
ENV NGINX_CONF_DIR "/etc/nginx/default.d"
ENV NGINX_LOG_DIR "/var/log/nginx"
ENV NGINX_CONF "/etc/nginx/nginx.conf"
ENV WWW_DIR "/usr/share/nginx/html"
# Install Nginx and clear the yum cache
RUN dnf install -y nginx \
&& dnf clean all \
&& rm -rf /var/cache/yum
# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout ${NGINX_LOG_DIR}/access.log \
&& ln -sf /dev/stderr ${NGINX_LOG_DIR}/error.log
# Listen on port 8080, so root privileges are not required for podman
RUN sed -i -E 's/(listen)([[:space:]]*)(\[\:\:\]\:)?80;$/\1\2\38080 default_server;/' $NGINX_CONF
EXPOSE 8080
# Allow Nginx PID to be managed by non-root user
RUN sed -i '/user nginx;/d' $NGINX_CONF
RUN sed -i 's/pid \/run\/nginx.pid;/pid \/tmp\/nginx.pid;/' $NGINX_CONF
# Run as an unprivileged user
USER 1001
CMD ["nginx", "-g", "daemon off;"]
```
注:本例中使用的容器文件和其他文件可以在本项目的 [GitHub 仓库][9]中找到。
上面容器文件中最重要的部分是改变日志存储方式的部分(写到 STDOUT 而不是文件),这样你就可以在容器日志中看到进入该服务器的请求。其他的一些改变使你可以在没有 root 权限的情况下使用 Podman 运行容器,也可以在没有 root 权限的情况下运行容器中的进程。
在 Web 服务器上的第一个测试并不提供任何 Cloud-init 数据;只是用它来查看 Cloud-init 客户端的请求。
创建容器文件后,使用 Podman 构建并运行 Web 服务器镜像:
```
# Build the container image
$ podman build -f Containerfile -t cloud-init:01 .
# Create a container from the new image, and run it
# It will listen on port 8080
$ podman run --rm -p 8080:8080 -it cloud-init:01
```
这会运行一个容器,让你的终端连接到一个伪 TTY。一开始看起来什么都没有发生但是对主机 8080 端口的请求会被路由到容器内的 Nginx 服务器,并且在终端窗口中会出现一条日志信息。这一点可以用主机上的 `curl` 命令进行测试。
```
# Use curl to send an HTTP request to the Nginx container
$ curl http://localhost:8080
```
运行该 `curl` 命令后,你应该会在终端窗口中看到类似这样的日志信息:
```
127.0.0.1 - - [09/May/2020:19:25:10 +0000] "GET / HTTP/1.1" 200 5564 "-" "curl/7.66.0" "-"
```
现在,有趣的部分来了:重启 Cloud-init 客户端,并观察 Nginx 日志,看看当客户端启动时, Cloud-init 向 Web 服务器发出了什么请求。
当客户端完成其启动过程时,你应该会看到类似的日志消息。
```
2020/05/09 22:44:28 [error] 2#0: *4 open() "/usr/share/nginx/html/meta-data" failed (2: No such file or directory), client: 127.0.0.1, server: _, request: "GET /meta-data HTTP/1.1", host: "instance-data:8080"
127.0.0.1 - - [09/May/2020:22:44:28 +0000] "GET /meta-data HTTP/1.1" 404 3650 "-" "Cloud-Init/17.1" "-"
```
注:使用 `Ctrl+C` 停止正在运行的容器。
你可以看到请求是针对 `/meta-data` 路径的,即 `http://ip_address_of_the_webserver:8080/meta-data`。这只是一个 GET 请求 —— Cloud-init 并没有向 Web 服务器发送任何数据。它只是盲目地从数据源 URL 中请求文件,所以要由数据源来识别主机的要求。这个简单的例子只是向任何客户端发送通用数据,但一个更大的家庭实验室应该需要更复杂的服务。
在这里Cloud-init 请求的是[实例元数据][10]信息。这个文件可以包含很多关于实例本身的信息,例如实例 ID、分配实例的主机名、云 ID甚至网络信息。
创建一个包含实例 ID 和主机名的基本元数据文件,并尝试将其提供给 Cloud-init 客户端。
首先,创建一个可复制到容器镜像中的 `meta-data` 文件。
```
instance-id: iid-local01
local-hostname: raspberry
hostname: raspberry
```
实例 ID`instance-id`)可以是任何东西。但是,如果你在 Cloud-init 运行后更改实例 ID并且文件被送达客户端就会触发 Cloud-init 再次运行。你可以使用这种机制来更新实例配置,但你应该意识到它是这种工作方式。
`local-hostname``hostname` 键正如其名,它们会在 Cloud-init 运行时为客户端设置主机名信息。
在容器文件中添加以下行以将 `meta-data` 文件复制到新镜像中。
```
# Copy the meta-data file into the image for Nginx to serve it
COPY meta-data ${WWW_DIR}/meta-data
```
现在,用元数据文件重建镜像(使用一个新的标签以方便故障排除),并用 Podman 创建并运行一个新的容器。
```
# Build a new image named cloud-init:02
podman build -f Containerfile -t cloud-init:02 .
# Run a new container with this new meta-data file
podman run --rm -p 8080:8080 -it cloud-init:02
```
新容器运行后,重启 Cloud-init 客户端,再次观察 Nginx 日志。
```
127.0.0.1 - - [09/May/2020:22:54:32 +0000] "GET /meta-data HTTP/1.1" 200 63 "-" "Cloud-Init/17.1" "-"
2020/05/09 22:54:32 [error] 2#0: *2 open() "/usr/share/nginx/html/user-data" failed (2: No such file or directory), client: 127.0.0.1, server: _, request: "GET /user-data HTTP/1.1", host: "instance-data:8080"
127.0.0.1 - - [09/May/2020:22:54:32 +0000] "GET /user-data HTTP/1.1" 404 3650 "-" "Cloud-Init/17.1" "-"
```
你看,这次 `/meta-data` 路径被提供给了客户端。成功了!
然而,客户端接着在 `/user-data` 路径上寻找第二个文件。该文件包含实例所有者提供的配置数据,而不是来自云提供商的数据。对于一个家庭实验室来说,这两个都是你自己提供的。
你可以使用[许多 user-data 模块][11]来配置你的实例。对于这个例子,只需使用 `write_files` 模块在客户端创建一些测试文件,并验证 Cloud-init 是否工作。
创建一个包含以下内容的用户数据文件:
```
#cloud-config
# Create two files with example content using the write_files module
write_files:
 - content: |
    "Does cloud-init work?"
   owner: root:root
   permissions: '0644'
   path: /srv/foo
 - content: |
   "IT SURE DOES!"
   owner: root:root
   permissions: '0644'
   path: /srv/bar
```
除了使用 Cloud-init 提供的 `user-data` 模块制作 YAML 文件外,你还可以将其制作成一个可执行脚本供 Cloud-init 运行。
创建 `user-data` 文件后,在容器文件中添加以下行,以便在重建映像时将其复制到镜像中:
```
# Copy the user-data file into the container image
COPY user-data ${WWW_DIR}/user-data
```
重建镜像,并创建和运行一个新的容器,这次使用用户数据信息:
```
# Build a new image named cloud-init:03
podman build -f Containerfile -t cloud-init:03 .
# Run a new container with this new user-data file
podman run --rm -p 8080:8080 -it cloud-init:03
```
现在,重启 Cloud-init 客户端,观察 Web 服务器上的 Nginx 日志:
```
127.0.0.1 - - [09/May/2020:23:01:51 +0000] "GET /meta-data HTTP/1.1" 200 63 "-" "Cloud-Init/17.1" "-"
127.0.0.1 - - [09/May/2020:23:01:51 +0000] "GET /user-data HTTP/1.1" 200 298 "-" "Cloud-Init/17.1" "-
```
成功了!这一次,元数据和用户数据文件都被送到了 Cloud-init 客户端。
### 验证 Cloud-init 已运行
从上面的日志中,你知道 Cloud-init 在客户端主机上运行并请求元数据和用户数据文件,但它用它们做了什么?你可以在 `write_files` 部分验证 Cloud-init 是否写入了你在用户数据文件中添加的文件。
在 Cloud-init 客户端上,检查 `/srv/foo``/srv/bar` 文件的内容:
```
# cd /srv/ && ls
bar foo
# cat foo
"Does cloud-init work?"
# cat bar
"IT SURE DOES!"
```
成功了!文件已经写好了,并且有你期望的内容。
如上所述,还有很多其他模块可以用来配置主机。例如,用户数据文件可以配置成用 `apt` 添加包、复制 SSH 的 `authorized_keys`、创建用户和组、配置和运行配置管理工具等等。我在家里的私有云中使用它来复制我的 `authorized_keys`、创建一个本地用户和组,并设置 sudo 权限。
### 你接下来可以做什么
Cloud-init 在家庭实验室中很有用,尤其是专注于云技术的实验室。本文所演示的简单服务对于家庭实验室来说可能并不是超级有用,但现在你已经知道 Cloud-init 是如何工作的了,你可以继续创建一个动态服务,可以用自定义数据配置每台主机,让家里的私有云更类似于主流云提供商提供的服务。
在数据源稍显复杂的情况下,将新的物理(或虚拟)机器添加到家中的私有云中,可以像插入它们并打开它们一样简单。
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/5/create-simple-cloud-init-service-your-homelab
作者:[Chris Collins][a]
选题:[lujun9972][b]
译者:[wxy](https://github.com/wxy)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/clcollins
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_desk_home_laptop_browser.png?itok=Y3UVpY0l (Digital images of a computer desktop)
[2]: https://cloudinit.readthedocs.io/
[3]: https://linux.cn/article-12371-1.html
[4]: https://opensource.com/sites/default/files/uploads/cloud-init.jpg (A screen showing the boot process for a Linux server running Cloud-init )
[5]: https://creativecommons.org/licenses/by-sa/4.0/
[6]: https://linux.cn/article-12277-1.html
[7]: https://cloudinit.readthedocs.io/en/latest/topics/datasources.html
[8]: https://podman.io/
[9]: https://github.com/clcollins/homelabCloudInit/tree/master/simpleCloudInitService/data
[10]: https://cloudinit.readthedocs.io/en/latest/topics/instancedata.html#what-is-instance-data
[11]: https://cloudinit.readthedocs.io/en/latest/topics/modules.html

View File

@ -1,8 +1,8 @@
[#]: collector: (lujun9972)
[#]: translator: (robsean)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: reviewer: (wxy)
[#]: publisher: (wxy)
[#]: url: (https://linux.cn/article-12404-1.html)
[#]: subject: (13 Things To Do After Installing Linux Mint 20)
[#]: via: (https://itsfoss.com/things-to-do-after-installing-linux-mint-20/)
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
@ -10,31 +10,33 @@
安装 Linux Mint 20 后需要做的 13 件事
======
Linux Mint 很容易成为 [最佳 Linux 发行版][1] 之一,特别是考虑到 [Linux Mint 20][2] 的特色,我确信你也会同意这一说法。
![](https://img.linux.net.cn/data/attachment/album/202007/11/113643ich99s7y7kw7ckw9.jpg)
假设你错过了我们的新闻报道,[可以下载Linux Mint 20 了][3]
Linux Mint 毫无疑问是 [最佳 Linux 发行版][1] 之一,特别是考虑到 [Linux Mint 20][2] 的功能,我确信你也会同意这一说法
当然,如果你使用 Linux Mint 有一段时间了,你可能知道最好做一些什么。但是,对于新用户来说,在安装 Linux Mint 20 后,你需要做的一些事来使你的体验更比以往任何时候都好
假设你错过了我们的新闻报道,[Linux Mint 20 终于可以下载了][3]
### 在安装 Linux Mint 20 后建议做的事
当然,如果你使用 Linux Mint 有一段时间了,你可能知道最好做一些什么。但是,对于新用户来说,在安装 Linux Mint 20 后,你需要做一些事,让你的体验更比以往任何时候都好。
### 在安装 Linux Mint 20 后建议做的事
在这篇文章中,我将列出其中一些要做的事来帮助你改善 Linux Mint 20 的用户体验。
#### 1\. 执行一次系统更新
#### 1执行一次系统更新
![][4]
如上图所示,在安装后,你应该立刻地用更新管理器检查 — 系统更新
安装后首先应该马上检查的是 —— 使用更新管理器进行系统更新,如上图所示
为什么?因为你需要构建可用软件的本地缓存。更新所有软件包的更新也是一个好意。
为什么?因为你需要构建可用软件的本地缓存。更新所有软件包的更新也是一个好意。
如果你喜欢使用终端,简单地输入下面的命令来执行一些系统更新:
如果你喜欢使用终端,只需输入下面的命令来执行系统更新:
```
sudo apt update && sudo apt upgrade -y
```
#### 2\. 使用 Timeshift 来创建系统快照
#### 2使用 Timeshift 来创建系统快照
![][5]
@ -42,9 +44,9 @@ sudo apt update && sudo apt upgrade -y
因此,如果你希望能够随时备份你的系统状态,那么使用 Timeshift 配置和创建系统快照是超级重要的。
你可以遵循我们 [使用 Timeshift][6] 的详细指南,如果你还不知道如何使用它的话
如果你还不知道如何使用它的话,你可以遵循我们 [使用 Timeshift][6] 的详细指南。
#### 3\. 安装有用的软件
#### 3安装有用的软件
尽管在 Linux Mint 20 中已经安装有一些有用的预安装应用程序,你可能需要安装一些没有随之一起出炉的必不可少的应用程序。
@ -52,6 +54,11 @@ sudo apt update && sudo apt upgrade -y
对于初学者来说,如果你想探索各种各样的工具,那么你可以遵循我们的 [必不可少的 Linux 应用程序][7] 的列表。
也参见:
- [75 个最常用的 Linux 应用程序2018 年)](https://linux.cn/article-10099-1.html)
- 100 个最佳 Ubuntu 应用([上](https://linux.cn/article-11044-1.html)、[中](https://linux.cn/article-11048-1.html)、[下](https://linux.cn/article-11057-1.html)
这里是一个我最喜欢的软件包列表,我希望你也来尝试一下:
* [VLC 多媒体播放器][8] 用于视频播放
@ -60,9 +67,7 @@ sudo apt update && sudo apt upgrade -y
* [Stacer][11] 用来优化和监控系统
* [ActivityWatch][12] 用来跟踪你的屏幕时间并保持高效唤醒
#### 4\. 自定义主题和图标
#### 4、自定义主题和图标
![][13]
@ -70,45 +75,45 @@ sudo apt update && sudo apt upgrade -y
但是,[在 Linux Mint 中更改主题和图标是非常容易的][14] ,而不需要安装任何额外的东西。
你会在欢迎屏幕中获得优化外观的选项。在任何情况下,你只需要进入 **主题**”,并开始自定义主题。
你会在欢迎屏幕中获得优化外观的选项。或者,你只需要进入 “主题”,并开始自定义主题。
![][15]
为此,你可以搜索它或在系统设置中如上图所示找到它。
为此,你可以搜索它或在系统设置中如上图所示找到它。
根据你正在使用的桌面环境,你也可以看看可用的 [最佳图标主题][16]。
#### 5\. 启用 Redshift 来保护你的眼睛
#### 5启用 Redshift 来保护你的眼睛
![][17]
你可以在 Linux Mint 上搜索“[Redshift][18]”,并在晚上启动它以保护你的眼睛。如你在上面的截图所见,它将根据时间自动地调整屏幕的色温。
你可以在 Linux Mint 上搜索 “[Redshift][18]”,并启用它以在晚上保护你的眼睛。如你在上面的截图所见,它将根据时间自动地调整屏幕的色温。
你可能想启用自动启动选项,以便它在你重新启动计算机时自动启动。它不可能与 [Ubuntu 20.04 LTS][19] 的夜光特色相同,但是如果你不需要自定义时间表或微调色温的能力,那么它就足够好了。
你可能想启用自动启动选项,以便它在你重新启动计算机时自动启动。它可能与 [Ubuntu 20.04 LTS][19] 的夜光功能不太一样,但是如果你不需要自定义时间表或微调色温的能力,那么它就足够好了。
#### 6\. 启用 snap (如果需要的话)
#### 6、启用 snap如果需要的话
尽管 Ubuntu 比因为任何时候都更倾向于推动使用 Snap ,但是 Linux Mint 团队反对使用它。因此,它禁止 APT 使用 snapd
尽管 Ubuntu 比前所未有的更倾向于推崇使用 Snap但是 Linux Mint 团队却反对使用它。因此,它禁止 APT 使用 snapd。
因此,你将没有 snap 开箱即用的支持。然而,你迟早会意识到一些软件包只以 Snap 的格式打包。在这种情况下,你将不得不在 Mint 上启用对 snap 的支持。
因此,你将无法获得 snap 开箱即用的支持。然而,你迟早会意识到一些软件包只以 Snap 的格式打包。在这种情况下,你将不得不在 Mint 上启用对 snap 的支持。
```
sudo apt install snapd
```
在你完成后,你可以遵循我们的指南来了解更多关于 [在 Linux 上安装和使用 snaps][20] 的信息。
在你完成后,你可以遵循我们的指南来了解更多关于 [在 Linux 上安装和使用 snap][20] 的信息。
#### 7\. 学习使用 Flatpak
#### 7学习使用 Flatpak
默认情况下Linux Mint 带有对 Flatpak 的支持。所以,不管你是讨厌使用 snap 或只是更喜欢使用 Flatpak在系统中保留它是极好的主意。
默认情况下Linux Mint 带有对 Flatpak 的支持。所以,不管你是讨厌使用 snap 或只是更喜欢使用 Flatpak在系统中保留它是个好主意。
现在,你只需要遵循我们关于 [在 Linux 上使用 Flatpak][21] 的指南来开始吧!
#### 8\. 清理或优化你的系统
#### 8清理或优化你的系统
优化或清理系统以清除无价值的占用存储空间的垃圾文件总是很好的
优化或清理系统总是好的,以避免不必要的垃圾文件占用存储空间
你可以从你的系统中快速移除不想要的软件包,通过在你的终端中输入这个命令
你可以通过在终端机上输入以下内容,快速删除系统中不需要的软件包
```
sudo apt autoremove
@ -116,53 +121,53 @@ sudo apt autoremove
除此之外,你也可以遵循我们 [在 Linux Mint 上释放空间的一些建议][22] 。
#### 9\. 使用 Warpinator 通过网络发送/接收文件
#### 9使用 Warpinator 通过网络发送/接收文件
Warpinator 是 Linux Mint 20 的一个新特色,给予你在连接同一个网络的多台计算机上共享文件的能力。这里是它看起来的样子:
Warpinator 是 Linux Mint 20 的一个新功能,可以让你在连接到网络的多台电脑上共享文件。这里是它看起来的样子:
![][23]
你只需要在菜单中搜索它就可以开始了!
你只需要在菜单中搜索它就可以开始了
#### 10\. 使用驱动器管理器
#### 10、使用驱动程序管理器
![驱动器管理器][24]
如果你正在使用需要一个驱动程序的 Wi-Fi 设备NVIDIA 显卡, 或 AMD 显卡,和其它设备(如果可应用的话)的驱动程序时,驱动器管理器是一个重要的查找位置
如果你正在使用需要驱动程序的 Wi-Fi 设备、NVIDIA 显卡或 AMD 显卡,以及其它设备(如果适用的话)时,驱动程序管理器是一个重要的部分
你只需要找到驱动器管理器并启动它。它应该可以侦察出在使用的一些专有驱动程序,或者你也可以使用驱动器管理器来利用 DVD 碟片来安装驱动程序。
你只需要找到驱动程序管理器并启用它。它应该可以检测到正在使用的任何专有驱动程序,或者你也可以使用驱动程序管理器来利用 DVD 来安装驱动程序。
#### 11\. 设置防火墙
#### 11设置防火墙
![][25]
在大多数情况下,你可能已经实现了你的家庭联网。但是,如果你想在 Linux Mint 上有一些特殊的防火墙设置,你可以通过在菜单中搜索 “Firewall” 来实现。
在大多数情况下,你可能已经保护了你的家庭网络。但是,如果你想在 Linux Mint 上有一些特殊的防火墙设置,你可以通过在菜单中搜索 “Firewall” 来实现。
正如你在上述截图中所看到的,你有能力为家庭,商业和公众做出不同的概述。你只需要添加是否被允许访问互联网的规则和定义
正如你在上述截图中所看到的,你可以为家庭、企业和公共设置不同的配置文件。你只需要添加规则,并定义什么是允许访问互联网的,什么是不允许的
你可以阅读我们关于 [使用 UFW 配置防火墙][26] 的详细指南。
#### 12\. 学习管理 Startup 应用程序
#### 12、学习管理启动应用程序
如果你是一个有经验的用户,你可能已经知道这一点了。但是,新用户经常忘记管理他们的 startup 应用程序,最终,系统的启动时间将会受到影响
如果你是一个有经验的用户,你可能已经知道这一点了。但是,新用户经常忘记管理他们的启动应用程序,最终影响了系统启动时间
你只需要从菜单中搜索 “**Startup Applications**” ,你可以启动它来查找像这样的东西:
你只需要从菜单中搜索 “Startup Applications” ,你可以启动它来查找像这样的东西
![][27]
你可以简单地切换你想要禁用的那些 Startup 应用程序,添加一个延迟计时器,或从 startup 应用程序的列表中完全地移除
你可以简单地切换你想要禁用的那些启动应用程序,添加一个延迟计时器,或从启动应用程序的列表中完全地移除它
#### 13\. 安装必不可少的游戏应用程序
#### 13安装必不可少的游戏应用程序
当然,如果你对游戏感兴趣,你可能想去阅读我们关于 [在 Linux 上的游戏][28] 的文章来探索所有的选
当然,如果你对游戏感兴趣,你可能想去阅读我们关于 [在 Linux 上的游戏][28] 的文章来探索所有的选
但是,对于初学者来说,你可以尝试安装 [GameHub][29], [Steam][30],和 [Lutris][31] 来玩一些游戏。
但是,对于初学者来说,你可以尝试安装 [GameHub][29]、[Steam][30] 和 [Lutris][31] 来玩一些游戏。
**总结**
### 总结
就是这样,各位!在大多数情况下,如果你在安装 Linux Mint 20 后遵循上面的几点,你应该可以很好地使用它
就是这样,各位!在大多数情况下,如果你在安装 Linux Mint 20 后按照上面的要点进行操作,使其发挥出最好的效果,应该就可以了
我确信你还能够做更多的事。现在,我想知道,你在安装 Linux Mint 20 后,更喜欢去做的事。让我在评论区知道你的想法
我确信你还能够做更多的事。我想知道你喜欢在安装 Linux Mint 20 后马上做了什么。在下面的评论中告诉我你的想法吧
--------------------------------------------------------------------------------
@ -171,19 +176,19 @@ via: https://itsfoss.com/things-to-do-after-installing-linux-mint-20/
作者:[Ankush Das][a]
选题:[lujun9972][b]
译者:[robsean](https://github.com/robsean)
校对:[校对者ID](https://github.com/校对者ID)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/ankush/
[b]: https://github.com/lujun9972
[1]: https://itsfoss.com/best-linux-distributions/
[2]: https://itsfoss.com/linux-mint-20/
[3]: https://itsfoss.com/linux-mint-20-download/
[2]: https://linux.cn/article-12297-1.html
[3]: https://linux.cn/article-12376-1.html
[4]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2020/06/linux-mint-20-system-update.png?ssl=1
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2018/07/snapshot-linux-mint-timeshift.jpeg?ssl=1
[6]: https://itsfoss.com/backup-restore-linux-timeshift/
[7]: https://itsfoss.com/essential-linux-applications/
[6]: https://linux.cn/article-11619-1.html
[7]: https://linux.cn/article-10165-1.html
[8]: https://www.videolan.org/vlc/
[9]: https://itsfoss.com/freefilesync/
[10]: https://itsfoss.com/flameshot/

View File

@ -1,334 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Add nodes to your private cloud using Cloud-init)
[#]: via: (https://opensource.com/article/20/5/create-simple-cloud-init-service-your-homelab)
[#]: author: (Chris Collins https://opensource.com/users/clcollins)
Add nodes to your private cloud using Cloud-init
======
Make adding machines to your private cloud at home similar to how the
major cloud providers handle it.
![Digital images of a computer desktop][1]
[Cloud-init][2] is a widely utilized industry-standard method for initializing cloud instances. Cloud providers use Cloud-init to customize instances with network configuration, instance information, and even user-provided configuration directives. It is also a great tool to use in your "private cloud at home" to add a little automation to the initial setup and configuration of your homelab's virtual and physical machines—and to learn more about how large cloud providers work. For a bit more detail and background, see my previous article on [Cloud-init and why it is useful][3].
![A screen showing the boot process for a Linux server running Cloud-init ][4]
Boot process for a Linux server running Cloud-init (Chris Collins, [CC BY-SA 4.0][5])
Admittedly, Cloud-init is more useful for a cloud provider provisioning machines for many different clients than for a homelab run by a single sysadmin, and much of what Cloud-init solves might be a little superfluous for a homelab. However, getting it set up and learning how it works is a great way to learn more about this cloud technology, not to mention that it's a great way to configure your devices on first boot.
This tutorial uses Cloud-init's "NoCloud" datasource, which allows Cloud-init to be used outside a traditional cloud provider setting. This article will show you how to install Cloud-init on a client device and set up a container running a web service to respond to the client's requests. You will also learn to investigate what the client is requesting from the web service and modify the web service's container to serve a basic, static Cloud-init service.
### Set up Cloud-init on an existing system
Cloud-init probably is most useful on a new system's first boot to query for configuration data and make changes to customize the system as directed. It can be [included in a disk image for Raspberry Pis and single-board computers][6] or added to images used to provision virtual machines. For testing, it is easy to install and run Cloud-init on an existing system or to install a new system and then set up Cloud-init.
As a major service used by most cloud providers, Cloud-init is supported on most Linux distributions. For this example, I will be using Fedora 31 Server for the Raspberry Pi, but it can be done the same way on Raspbian, Ubuntu, CentOS, and most other distributions.
#### Install and enable the cloud-init services
On a system that you want to be a Cloud-init client, install the Cloud-init package. If you're using Fedora:
```
# Install the cloud-init package
dnf install -y cloud-init
```
Cloud-init is actually four different services (at least with systemd), and each is in charge of retrieving config data and performing configuration changes during a different part of the boot process, allowing greater flexibility in what can be done. While it is unlikely you will interact much with these services directly, it is useful to know what they are in the event you need to troubleshoot something. They are:
* cloud-init-local.service
* cloud-init.service
* cloud-config.service
* cloud-final.service
Enable all four services:
```
# Enable the four cloud-init services
systemctl enable cloud-init-local.service
systemctl enable cloud-init.service
systemctl enable cloud-config.service
systemctl enable cloud-final.service
```
#### Configure the datasource to query
Once the service is enabled, configure the datasource from which the client will query the config data. There are a [large number of datasource types][7], and most are configured for specific cloud providers. For your homelab, use the NoCloud datasource, which (as mentioned above) is designed for using Cloud-init without a cloud provider.
NoCloud allows configuration information to be included a number of ways: as key/value pairs in kernel parameters, for using a CD (or virtual CD, in the case of virtual machines) mounted at startup, in a file included on the filesystem, or, as in this example, via HTTP from a specified URL (the "NoCloud Net" option).
The datasource configuration can be provided via the kernel parameter or by setting it in the Cloud-init configuration file, `/etc/cloud/cloud.cfg`. The configuration file works very well for setting up Cloud-init with customized disk images or for testing on existing hosts.
Cloud-init will also merge configuration data from any `*.cfg` files found in `/etc/cloud/cloud.cfg.d/`, so to keep things cleaner, configure the datasource in `/etc/cloud/cloud.cfg.d/10_datasource.cfg`. Cloud-init can be told to read from an HTTP datasource with the seedfrom key by using the syntax:
```
`seedfrom: http://ip_address:port/`
```
The IP address and port are the web service you will create later in this article. I used the IP of my laptop and port 8080; this can also be a DNS name.
Create the `/etc/cloud/cloud.cfg.d/10_datasource.cfg` file:
```
# Add the datasource:
# /etc/cloud/cloud.cfg.d/10_datasource.cfg
# NOTE THE TRAILING SLASH HERE!
datasource:
  NoCloud:
    seedfrom: <http://ip\_address:port/>
```
That's it for the client setup. Now, when the client is rebooted, it will attempt to retrieve configuration data from the URL you entered in the seedfrom key and make any configuration changes that are necessary.
The next step is to set up a webserver to listen for client requests, so you can figure out what needs to be served.
### Set up a webserver to investigate client requests
You can create and run a webserver quickly with [Podman][8] or other container orchestration tools (like Docker or Kubernetes). This example uses Podman, but the same commands work with Docker.
To get started, use the Fedora:31 container image and create a Containerfile (for Docker, this would be a Dockerfile) that installs and configures Nginx. From that Containerfile, you can build a custom image and run it on the host you want to act as the Cloud-init service.
Create a Containerfile with the following contents:
```
FROM fedora:31
ENV NGINX_CONF_DIR "/etc/nginx/default.d"
ENV NGINX_LOG_DIR "/var/log/nginx"
ENV NGINX_CONF "/etc/nginx/nginx.conf"
ENV WWW_DIR "/usr/share/nginx/html"
# Install Nginx and clear the yum cache
RUN dnf install -y nginx \
      &amp;&amp; dnf clean all \
      &amp;&amp; rm -rf /var/cache/yum
# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout ${NGINX_LOG_DIR}/access.log \
    &amp;&amp; ln -sf /dev/stderr ${NGINX_LOG_DIR}/error.log
# Listen on port 8080, so root privileges are not required for podman
RUN sed -i -E 's/(listen)([[:space:]]*)(\\[\:\:\\]\:)?80;$/\1\2\38080 default_server;/' $NGINX_CONF
EXPOSE 8080
# Allow Nginx PID to be managed by non-root user
RUN sed -i '/user nginx;/d' $NGINX_CONF
RUN sed -i 's/pid \/run\/nginx.pid;/pid \/tmp\/nginx.pid;/' $NGINX_CONF
# Run as an unprivileged user
USER 1001
CMD ["nginx", "-g", "daemon off;"]
```
_Note: The example Containerfile and other files used in this example can be found in this project's [GitHub repository][9]._
The most important part of the Containerfile above is the section that changes how the logs are stored (writing to STDOUT rather than a file), so you can see requests coming into the server in the container logs. A few other changes enable you to run the container with Podman without root privileges and to run processes in the container without root, as well.
This first pass at the webserver does not serve any Cloud-init data; just use this to see what the Cloud-init client is requesting from it.
With the Containerfile created, use Podman to build and run a webserver image:
```
# Build the container image
$ podman build -f Containerfile -t cloud-init:01 .
# Create a container from the new image, and run it
# It will listen on port 8080
$ podman run --rm -p 8080:8080 -it cloud-init:01
```
This will run the container, leaving your terminal attached and with a pseudo-TTY. It will appear that nothing is happening at first, but requests to port 8080 of the host machine will be routed to the Nginx server inside the container, and a log message will appear in the terminal window. This can be tested with a curl command from the host machine:
```
# Use curl to send an HTTP request to the Nginx container
$ curl <http://localhost:8080>
```
After running that curl command, you should see a log message similar to this in the terminal window:
```
`127.0.0.1 - - [09/May/2020:19:25:10 +0000] "GET / HTTP/1.1" 200 5564 "-" "curl/7.66.0" "-"`
```
Now comes the fun part: reboot the Cloud-init client and watch the Nginx logs to see what Cloud-init requests from the webserver when the client boots up.
As the client finishes its boot process, you should see log messages similar to:
```
2020/05/09 22:44:28 [error] 2#0: *4 open() "/usr/share/nginx/html/meta-data" failed (2: No such file or directory), client: 127.0.0.1, server: _, request: "GET /meta-data HTTP/1.1", host: "instance-data:8080"
127.0.0.1 - - [09/May/2020:22:44:28 +0000] "GET /meta-data HTTP/1.1" 404 3650 "-" "Cloud-Init/17.1" "-"
```
_Note: Use Ctrl+C to stop the running container._
You can see the request is for the /meta-data path, i.e., `http://ip_address_of_the_webserver:8080/meta-data`. This is just a GET request—Cloud-init is not POSTing (sending) any data to the webserver. It is just blindly requesting the files from the datasource URL, so it is up to the datasource to identify what the host is asking. This simple example is just sending generic data to any client, but a larger homelab will need a more sophisticated service.
Here, Cloud-init is requesting the [instance metadata][10] information. This file can include a lot of information about the instance itself, such as the instance ID, the hostname to assign the instance, the cloud ID—even networking information.
Create a basic metadata file with an instance ID and a hostname for the host, and try serving that to the Cloud-init client.
First, create a metadata file that can be copied into the container image:
```
instance-id: iid-local01
local-hostname: raspberry
hostname: raspberry
```
The instance ID can be anything. However, if you change the instance ID after Cloud-init runs and the file is served to the client, it will trigger Cloud-init to run again. You can use this mechanism to update instance configurations, but you should be aware that it works that way.
The local-hostname and hostname keys are just that; they set the hostname information for the client when Cloud-init runs.
Add the following line to the Containerfile to copy the metadata file into the new image:
```
# Copy the meta-data file into the image for Nginx to serve it
COPY meta-data ${WWW_DIR}/meta-data
```
Now, rebuild the image (use a new tag for easy troubleshooting) with the metadata file, and create and run a new container with Podman:
```
# Build a new image named cloud-init:02
podman build -f Containerfile -t cloud-init:02 .
# Run a new container with this new meta-data file
podman run --rm -p 8080:8080 -it cloud-init:02
```
With the new container running, reboot your Cloud-init client and watch the Nginx logs again:
```
127.0.0.1 - - [09/May/2020:22:54:32 +0000] "GET /meta-data HTTP/1.1" 200 63 "-" "Cloud-Init/17.1" "-"
2020/05/09 22:54:32 [error] 2#0: *2 open() "/usr/share/nginx/html/user-data" failed (2: No such file or directory), client: 127.0.0.1, server: _, request: "GET /user-data HTTP/1.1", host: "instance-data:8080"
127.0.0.1 - - [09/May/2020:22:54:32 +0000] "GET /user-data HTTP/1.1" 404 3650 "-" "Cloud-Init/17.1" "-"
```
You see that this time the /meta-data path was served to the client. Success!
However, the client is looking for a second file at the /user-data path. This file contains configuration data provided by the instance owner, as opposed to data from the cloud provider. For a homelab, both of these are you.
There are a [large number of user-data modules][11] you can use to configure your instance. For this example, just use the write_files module to create some test files on the client and verify that Cloud-init is working.
Create a user-data file with the following content:
```
#cloud-config
# Create two files with example content using the write_files module
write_files:
 - content: |
    "Does cloud-init work?"
   owner: root:root
   permissions: '0644'
   path: /srv/foo
 - content: |
   "IT SURE DOES!"
   owner: root:root
   permissions: '0644'
   path: /srv/bar
```
In addition to a YAML file using the user-data modules provided by Cloud-init, you could also make this an executable script for Cloud-init to run.
After creating the user-data file, add the following line to the Containerfile to copy it into the image when the image is rebuilt:
```
# Copy the user-data file into the container image
COPY user-data ${WWW_DIR}/user-data
```
Rebuild the image and create and run a new container, this time with the user-data information:
```
# Build a new image named cloud-init:03
podman build -f Containerfile -t cloud-init:03 .
# Run a new container with this new user-data file
podman run --rm -p 8080:8080 -it cloud-init:03
```
Now, reboot your Cloud-init client, and watch the Nginx logs on the webserver:
```
127.0.0.1 - - [09/May/2020:23:01:51 +0000] "GET /meta-data HTTP/1.1" 200 63 "-" "Cloud-Init/17.1" "-"
127.0.0.1 - - [09/May/2020:23:01:51 +0000] "GET /user-data HTTP/1.1" 200 298 "-" "Cloud-Init/17.1" "-
```
Success! This time both the metadata and user-data files were served to the Cloud-init client.
### Validate that Cloud-init ran
From the logs above, you know that Cloud-init ran on the client host and requested the metadata and user-data files, but did it do anything with them? You can validate that Cloud-init wrote the files you added in the user-data file, in the write_files section.
On your Cloud-init client, check the contents of the `/srv/foo` and `/srv/bar` files:
```
# cd /srv/ &amp;&amp; ls
bar foo
# cat foo
"Does cloud-init work?"
# cat bar
"IT SURE DOES!"
```
Success! The files were written and have the content you expect.
As mentioned above, there are plenty of other modules that can be used to configure the host. For example, the user-data file can be configured to add packages with apt, copy SSH authorized_keys, create users and groups, configure and run configuration-management tools, and many other things. I use it in my private cloud at home to copy my authorized_keys, create a local user and group, and set up sudo permissions.
### What you can do next
Cloud-init is useful in a homelab, especially a lab focusing on cloud technologies. The simple service demonstrated in this article may not be super useful for a homelab, but now that you know how Cloud-init works, you can move on to creating a dynamic service that can configure each host with custom data, making a private cloud at home more similar to the services provided by the major cloud providers.
With a slightly more complicated datasource, adding new physical (or virtual) machines to your private cloud at home can be as simple as plugging them in and turning them on.
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/5/create-simple-cloud-init-service-your-homelab
作者:[Chris Collins][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/clcollins
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/computer_desk_home_laptop_browser.png?itok=Y3UVpY0l (Digital images of a computer desktop)
[2]: https://cloudinit.readthedocs.io/
[3]: https://opensource.com/article/20/5/cloud-init-raspberry-pi-homelab
[4]: https://opensource.com/sites/default/files/uploads/cloud-init.jpg (A screen showing the boot process for a Linux server running Cloud-init )
[5]: https://creativecommons.org/licenses/by-sa/4.0/
[6]: https://opensource.com/article/20/5/disk-image-raspberry-pi
[7]: https://cloudinit.readthedocs.io/en/latest/topics/datasources.html
[8]: https://podman.io/
[9]: https://github.com/clcollins/homelabCloudInit/tree/master/simpleCloudInitService/data
[10]: https://cloudinit.readthedocs.io/en/latest/topics/instancedata.html#what-is-instance-data
[11]: https://cloudinit.readthedocs.io/en/latest/topics/modules.html

View File

@ -1,93 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: (Yufei-Yan)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (What you need to know about hash functions)
[#]: via: (https://opensource.com/article/20/7/hash-functions)
[#]: author: (Mike Bursell https://opensource.com/users/mikecamel)
What you need to know about hash functions
======
It should be computationally implausible to work backwards from the
output hash to the input.
![City with numbers overlay][1]
There is a tool in the security practitioner's repertoire that's helpful for everyone to understand, regardless of what they do with computers: cryptographic hash functions. That may sound mysterious, technical, and maybe even boring, but I have a concise explanation of what hashes are and why they matter to you.
A cryptographic hash function, such as SHA-256 or MD5, takes as input a set of binary data (typically as bytes) and gives output that is hopefully unique for each set of possible inputs. The length of the output—"the hash"—for any particular hash function is typically the same for any pattern of inputs (for SHA-256, it is 32 bytes or 256 bits—the clue's in the name). The important thing is this: It should be computationally implausible (cryptographers hate the word _impossible_) to work backward from the output hash to the input. This is why they are sometimes referred to as one-way hash functions.
But what are hash functions used for? And why is the property of being unique so important?
### Unique output
The phrase "hopefully unique" when describing the output of a hash function is vital because hash functions are used to render wholly unique output. Hash functions, for example, are used as a way to verify that the copy of a file _you_ downloaded is a byte-for-byte duplicate of the file _I_ downloaded. You'll see this verification process at work when you download a Linux ISO, or software from a Linux repository. Without uniqueness, the technology is rendered useless, at least for the purpose you generally have for it.
Should two inputs yield the same output, the hash is said to have a "collision." In fact, MD5 has become deprecated because it is now trivially possible to find collisions with commercially available hardware and software systems.
Another important property is that a tiny change in a message, even changing a single bit, is expected to generate a noticeable change to the output (this is the "avalanche effect").
### Verifying binary data
The typical use for hash functions is to ensure that when someone hands you a piece of binary data, it is what you expect. All data in the world of computing can be described in binary format, whether it is text, an executable, a video, an image, or a complete database of data, so hashes are broadly applicable, to say the least. Comparing binary data directly is slow and arduous computationally, but hash functions are designed to be very quick. Given two files several megabytes or gigabytes in size, you can produce hashes of them ahead of time and defer the comparisons to when you need them.
It's also generally easier to digitally sign hashes of data rather than large sets of data themselves. This is such an important feature that one of the most common uses of hashes in cryptography is to generate "digital" signatures.
Given the fact that it is easy to produce hashes of data, there's often no need to have both sets of data. Let's say you want to run an executable file on your computer. Before you do, though, you want to check that it really is the file you think it is and that no malicious actor has tampered with it. You can hash that file very quickly and easily, and as long as you have a copy of what the hash should look like, you can be fairly certain you have the file you want.
Here's a simple example:
```
$ shasum -a256 ~/bin/fop
87227baf4e1e78f6499e4905e8640c1f36720ae5f2bd167de325fd0d4ebc791c  /home/bob/bin/fop
```
If I know that the SHA-256 sum of the `fop` executable, as delivered by its vendor (Apache Foundation, in this case) is:
```
`87227baf4e1e78f6499e4905e8640c1f36720ae5f2bd167de325fd0d4ebc791c`
```
then I can be confident that the executable on my drive is indeed the same executable that Apache Foundation distributes on its website. This is where the lack of collisions (or at least the _difficulty in computing collisions_) property of hash functions is so important. If a malicious actor can craft a _replacement_ file that shares the same hash as the real file, then the process of verification is essentially useless.
In fact, there are more technical names for the various properties, and what I've described above mashes three important ones together. More accurately, those technical names are:
1. **Pre-image resistance:** Given a hash, it should be difficult to find the message from which it was created, even if you know the hash function used.
2. **Second pre-image resistance:** Given a message, it should be difficult to find another message that, when hashed, generates the same hash.
3. **Collision resistance:** It should be difficult to find any two messages that generate the same hash.
_Collision resistance_ and _second pre-image resistance_ may sound like the same property, but they're subtly (and significantly) different. Pre-image resistance says that if you _already_ have a message, you will not be able to find another message with a matching hash. Collision resistance makes it hard for you to invent two messages that will generate the same hash and is a much harder property to fulfill in a hash function.
Allow me to return to the scenario of a malicious actor attempting to exchange a file (with a hash, which you can check) with another one. Now, to use cryptographic hashes "in the wild"—out there in the real world, beyond the perfectly secure, bug-free implementations populated by unicorns and overflowing with fat-free doughnuts—there are some important and difficult provisos that need to be met. Very paranoid readers may already have spotted some of them; in particular:
1. You must have assurances that the copy of the hash you have has also not been subject to tampering.
2. You must have assurances that the entity performing the hash performs and reports it correctly.
3. You must have assurances that the entity comparing the two hashes does indeed report the result of that comparison correctly.
Ensuring that you can meet such assurances is not necessarily an easy task. This is one of the reasons Trusted Platform Modules (TPMs) are part of many computing systems. They act as a hardware root of trust with capabilities to provide assurances about the cryptography tools verifying the authenticity of important binary data. TPMs are a useful and important tool for real-world systems, and I plan to write an article about them in the future.
* * *
_This article was originally published on [Alice, Eve, and Bob][2] and is adapted and reprinted with the author's permission._
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/7/hash-functions
作者:[Mike Bursell][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/mikecamel
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_OpenData_CityNumbers.png?itok=lC03ce76 (City with numbers overlay)
[2]: https://aliceevebob.com/2020/06/16/whats-a-hash-function/

View File

@ -0,0 +1,92 @@
[#]: collector: (lujun9972)
[#]: translator: (Yufei-Yan)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (What you need to know about hash functions)
[#]: via: (https://opensource.com/article/20/7/hash-functions)
[#]: author: (Mike Bursell https://opensource.com/users/mikecamel)
关于哈希函数你应该知道的东西
======
通过哈希计算,从输出反推回输入,这从计算的角度是不可行的。
![City with numbers overlay][1]
无论安全从业人员用计算机做什么,在他们的技能库中有一个对所有人都很有用的工具:加密哈希函数。听起来很神秘,很专业,甚至可能有点无聊,但是关于什么是哈希函数以及他们为什么对你很重要,我会作出一个简洁的解释。
加密哈系函数,比如 SHA-256 或者 MD5接受一组二进制数据通常是字节作为输入并且希望给出对应每一组可能的输入一个唯一的输出。对于任意模式的输入给定哈希函数的输出长度——“哈希值”——通常都是一样对于 SHA-256他是 32 字节或者 256 比特——从名字中就能看出来)。重要的是:通过哈希计算,从输出反推回输入,这从计算的角度是<ruby>不可能的<rt>implausible</rt></ruby>(密码学家讨厌 _impossible_ 这个词)。这就是为什么他们有时候被称作<ruby>单向哈希函数<rt>one-way hash functions</rt></ruby>
但是哈希函数是干什么用的呢?什么独一无二的属性如此重要?
### 唯一的输出
在描述哈希函数的输出时,<ruby>“但愿唯一<rt>hopefully unique</rt></ruby>是非常关键的,因为哈希函数就是用来呈现完全唯一的输出。比如,哈希函数用于验证 _你_ 下载的文件副本的每一个字节是否和 _我_ 下载的文件一样。当你下载一个 Linux 的 ISO 文件或者从 Linux 的仓库中下载软件,你会看到这个验证过程正在工作。没有了唯一性,这个技术就没用了,至少就通常的目的而言是这样的。
如果两个输入产生了相同的输出,那么这样的哈希就称作<ruby>“冲突”<rt>collision</rt></ruby>。事实上MD5 已经被弃用,因为他现在非常可能与商业化的硬件和软件系统存在冲突。
另外一个重要的性质是,当消息中的一个微小变化,甚至只是一个比特位,都可能会在输出中产生一个明显的变化(这就是<ruby>“雪崩效应”<rt>avalanche effect</rt></ruby>)。
### 验证二进制数据
哈希函数的典型用途是当有人给你一段二进制数据,确保这些数据是你所期望的。无论是文本,可执行文件,视频,图像或者一个完整的数据库数据,在计算世界中,所有的数据都可以用二进制的形式进行描述,所以可以这么说,哈希的应用相当广泛。直接比较二进制数据非常缓慢且计算量巨大,但是哈希函数在设计之初就非常快。给定两个大小为几 M 或者几 G 的文件,你可以先生成他们的哈希值,然后在需要的时候再进行比较。
通常,对哈希值进行签名比对大型数据集本身进行签名更容易。这个特性太重要了,以至于密码学中对哈希值最常见的应用就是生成“数字”签名。
由于生成数据的哈希值很容易,所以通常不需要有两套数据。假设你想在你的电脑上运行一个可执行文件。但是在你运行之前,你需要检查这个文件就是你要的文件,并且没有被黑客篡改。你可以方便快捷的对文件生成哈希值,只要你有一个这个哈希值的副本,你就可以相当肯定这就是你想要的文件。
下面是一个简单的例子:
```
$ shasum -a256 ~/bin/fop
87227baf4e1e78f6499e4905e8640c1f36720ae5f2bd167de325fd0d4ebc791c  /home/bob/bin/fop
```
If I know that the SHA-256 sum of the `fop` executable, as delivered by its vendor (Apache Foundation, in this case) is:
如果我知道 fop 这个可执行文件的 SHA-256 的和,这由供应商(这个例子中是 Apache 基金会)提供的:
```
87227baf4e1e78f6499e4905e8640c1f36720ae5f2bd167de325fd0d4ebc791c
```
然后我就可以确信,我驱动器上的这个可执行文件和 Apache 基金会网站上发布的文件是一模一样的。这就是哈希函数难以发生冲突(或者至少是 _很难通过计算得到冲突_)这个性质的重要之处。如果黑客能将与真实文件的哈希值相同的文件轻易的进行替换,那么这个验证过程就毫无用处。
In fact, there are more technical names for the various properties, and what I've described above mashes three important ones together. More accurately, those technical names are:
事实上,对于不同的性质有更多的技术名称,而我将上面的描述总结成了三条。更准确的说,那些技术名称是:
1. **<ruby>抗原像性<rt>pre-image resistance</rt></ruby>** 给定一个哈希值,即使知道用了什么哈希函数,也无法得到能够得出这个哈希值的消息。
2. **<ruby>抗次原像性<rt>second pre-image resistance</rt><ruby>** 给定一个消息,无法得到另一个消息,使得这个消息可以产生相同的哈希值。
3. **<ruby>抗碰撞性<rt>collision resistance</rt></ruby>** 无法得到任意两个可以产生相同哈希值的消息。
_抗碰撞性_ 和 _抗原像性_ 也许听上去是同样的性质但他们有细微的和显著的不同。_抗原像性_ 说的是如果 _已经_ 有了一个消息,你也无法得到一个与之哈希值相匹配的消息。抗碰撞性使你很难制造两个可以生成相同哈希值的消息,并且要在哈希函数中实现这一性质则更加困难。
让我回到黑客试图替换文件(可以通过哈希值进行校验)的场景。现在,使用任意加密哈希算法——不是那些在现实世界中由独角兽公司开发的完全无 Bug 且安全的实现——有一些重要且困难的附加条件需要满足。偏执的读者可能已经想到了其中一些,特别需要指出的是:
1. 你必须确保现有的哈希值副本不容易遭到篡改。
2. 你必须确保执行哈希算法的实体可以正确执行并且得到正确的结果。
3. 你必须确保对比两个哈希值的实体可以得到这个对比的正确结果。
确保你能满足这些条件绝对不是一件容易的事。这就是<ruby>可信任平台模块<rt>Trusted Platform Modules</rt></ruby>TPMs成为许多计算系统一部分的原因之一。他们扮演着信任的硬件基础可以为验证重要二进制数据真实性的加密工具提供保证。 TPMs 对于现实中系统来说是有用且重要的工具,我也打算将来写一篇关于 TPMs 的文章。
* * *
_This article was originally published on [Alice, Eve, and Bob][2] and is adapted and reprinted with the author's permission._
--------------------------------------------------------------------------------
via: https://opensource.com/article/20/7/hash-functions
作者:[Mike Bursell][a]
选题:[lujun9972][b]
译者:[Yufei-Yan](https://github.com/Yufei-Yan)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/mikecamel
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/osdc_OpenData_CityNumbers.png?itok=lC03ce76 (City with numbers overlay)
[2]: https://aliceevebob.com/2020/06/16/whats-a-hash-function/