2020年11月

LVM 是一个逻辑卷管理工具,包括分配磁盘、条带化、镜像和调整逻辑卷的大小。它在 Fedora 安装中被普遍使用(在 BTRFS 作为默认文件系统之前是 LVM + Ext4)。但是你是否曾经遇到过启动系统时,GNOME 提示 home 卷几乎没有空间了!幸运的是,很有可能有一些空间在另一个卷中,而未被使用,可以用于重新分配。下面就来看看如何用 LVM 回收硬盘空间。

在卷之间轻松重新分配空间的关键是逻辑卷管理器(LVM)。Fedora 32 及以前的系统默认使用 LVM 来划分磁盘空间。这种技术类似于标准的硬盘分区,但 LVM 更加灵活。LVM 不仅可以实现灵活的卷大小管理,还可以实现一些高级功能,比如读写快照、在多个硬盘上进行数据条带化或镜像、将高速硬盘作为慢速硬盘的缓存等等。所有这些高级选项可能会让人有点不知所措,但调整卷的大小很简单的。

LVM 基础

卷组(VG)作为 LVM 系统中的主要容器。默认情况下,Fedora 只定义了一个卷组,但你可以根据需要定义多个卷组。实际的硬盘和硬盘分区被添加到卷组中作为物理卷(PV)。物理卷会将可用的空间添加到卷组中。一个典型的 Fedora 安装有一个格式化的启动分区,其余的硬盘是一个配置为 LVM 物理卷的分区。

从这个可用空间池中,卷组分配了一个或多个逻辑卷(LV)。这些卷类似于硬盘分区,但没有磁盘上连续空间的限制。LVM 的逻辑卷甚至可以跨越多个设备!就像硬盘分区一样,逻辑卷有一个定义的大小,可以包含任何文件系统,然后可以挂载到特定的目录。

需要什么

在 gnome-disks 应用中确认系统使用 LVM ,并确保其他卷中有可用的空间。如果没有可以从另一个卷中回收的空间,这个指南就没有用。还需要一个 Fedora 临场 CD/USB。任何需要收缩的文件系统都必须卸载。从 临场 Live 镜像运行,可以让硬盘上的所有卷保持未挂载状态,甚至包括像 //home 这样的重要目录。

Use gnome-disks to verify free space

一句话警告

按照这个指南,应该不会丢失任何数据,但它确实会使用一些非常底层和强大的命令。一个错误可能会破坏硬盘上的所有数据。所以要先备份磁盘上的所有数据!

调整 LVM 卷的大小

开始时,启动 Fedora 临场镜像并在对话框中选择 “Try Fedora”。接下来,使用 “Run Command” 启动 “blivet-gui” 应用(按 Alt-F2,输入 blivet-gui,然后按回车)。选择左侧 “LVM” 下的卷组。逻辑卷在右边。

Explore logical volumes in blivet-gui

逻辑卷标签由卷组名称和逻辑卷名称组成。在本例中,卷组是 fedora_localhost-live,分配了 homerootswap 逻辑卷。要找到完整的卷,选择每一个卷,点击“齿轮”图标,然后选择 “resize”。调整大小对话框中的滑块表示卷的允许大小。左边的最小值是文件系统中已经使用的空间,所以这是最小可能的尺寸大小(不删除数据)。右边的最大值是基于卷组中的最大可用空间。

Resize dialog in blivet-gui

灰色的 “resize” 选项意味着该卷已经满了,而且卷组中没有可用空间。

现在可以更改大小了!查看所有的卷,就像上面的截图那样,找到一个有足够空间的卷。并像上面的截图那样,在所有的卷中找到一个有大量额外空间的卷。向左移动滑块来设置新的大小。腾出足够的空间对整个卷有用,但仍然要为未来的数据增长留出足够的空间。否则,这个卷将是下一个被填满的卷。

点击 “resize”,注意卷列表中出现了一个新项目:“free space”。现在选择这次要调整的卷,并将滑块一直向右移动。按 “resize” 键,并查看新改进的卷的布局。然而,硬盘驱动器上的任何东西现在都还没有改变。点击“勾选”选项将更改提交到磁盘。

Review changes in blivet-gui

查看更改的摘要,如果一切看起来都是正确的,点击 “Ok” 继续。等待 “blivet-gui” 完成。现在重新启动回到 Fedora,可以使用之前被充满的卷上的新空间了。

为未来计划

要知道任何特定卷在未来需要多少空间是很困难的。与其立即分配所有可用的空闲空间,不如考虑在卷组中留出空闲空间。事实上,Fedora Server 默认在卷组中保留空间。当一个卷处于在线和使用中时,扩展卷是可能的。不需要临场镜像或重启。当一个卷几乎满的时候,可以使用部分可用空间轻松扩展卷并继续工作。遗憾的是,默认的磁盘管理器 gnome-disks 不支持 LVM 卷的大小调整,所以安装 blivet-gui 作为图形化管理工具。另外,还有一个简单的终端命令来扩展卷:

lvresize -r -L +1G /dev/fedora_localhost-live/root

总结

用 LVM 回收硬盘空间只是 LVM 功能的表面。大多数人,特别是在桌面中,可能不需要更高级的功能。然而,当需要的时候,LVM 就在那里,尽管它的实现可能会变得有点复杂。从 Fedora 33 开始,BTRFS 是默认的文件系统,没有 LVM。BTRFS 可以更容易管理,同时对于大多数常见的使用来说也足够灵活。查看最近 Fedora Magazine 关于 BTRFS 的文章了解更多。


via: https://fedoramagazine.org/reclaim-hard-drive-space-with-lvm/

作者:Troy Curtis Jr 选题:lujun9972 译者:geekpi 校对:wxy

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

用 Node.js 或其他编程语言为你提供启动基础设施所需的一切服务。

当你在 IT 和技术的世界里遨游时,你会反复遇到一些术语。其中有些术语很难量化,随着时间的推移,可能会有不同的含义。“DevOps” 就是一个例子,这个词似乎(在我看来)会根据使用它的人而改变;最初的 DevOps 先驱者可能甚至不认识我们今天所说的 DevOps。

如果你是一个软件开发者,“ 基础架构即代码 Infrastructure as Code ”(IaC)可能是其中一个术语。IaC 是使用与你编写面向用户的功能相同的软件开发实践来声明应用程序运行的基础设施。这通常意味着使用 GitMercurial 等工具进行版本控制,使用 Puppet、Chef 或 Ansible 进行配置管理。在基础设施供应层,最常见的技术是 CloudFormation(专用于 AWS),或开源替代品 Terraform,用来创建供你的应用程序运行的混合云资源。

在配置管理领域有很好产品可供选择,可以将 IaC 写成配置文件或首选的编程语言,但这种选择在基础设施供应领域并不常见。

Pulumi 提供了一个使用标准编程语言来定义基础设施的方式。它支持一系列语言,包括 JavaScriptTypeScriptGoPythonC#)。就像 Terraform 一样,Pulumi 对许多熟悉的云提供商有一流的支持,比如 AWSAzureGoogle Cloud其他提供商

在本文中,我将向你展示如何使用 Pulumi 以 Node.js 编写基础设施。

先决条件

首先,确保你已经做好了使用 Pulumi 的准备。Pulumi 支持所有主流的操作系统,所以你安装其先决条件的方法取决于你使用的操作系统。

首先,安装你喜欢的编程语言的解释器。我将使用 TypeScript,所以我需要安装 node 二进制。请查阅 Node 的安装说明,了解你的操作系统的信息。你可以在 MacLinux 上使用 Homebrew 来安装:

brew install node

在 Linux 上,你可以使用你常用的软件包管理器,如 aptdnf

$ sudo dnf install nodejs

无论哪种情况,结果都应该是 node 二进制文件在你的 $PATH 中可用。要确认它是可访问的,运行:

node --version

接下来,安装 Pulumi 命令行界面(CLI)。你可以在 Pulumi 的文档中找到针对不同操作系统的安装说明。在 Mac 或 Linux 上使用 brew

brew install pulumi

另外,你也可以使用安装脚本。首先下载并审查它,然后执行它:

$ curl -fsSL --output pulumi_installer.sh https://get.pulumi.com/
$ more  pulumi_installer.sh
$ sh ./pulumi_installer.sh

同样,我们所希望的结果是在你的路径上有 pulumi 二进制。检查版本以确保你已经准备好了:

pulumi version
v2.5.0

配置 Pulumi

在你开始配置任何基础设施之前,给 Pulumi 一个存储其状态的地方。

Pulumi 将其状态存储在后端。默认的后端是 Pulumi 的软件即服务(它有一个针对个人用户的免费计划),但在这个例子中,我使用替代的文件后端。文件后端将在你的本地文件系统上创建一个文件来存储状态:

pulumi login --local

如果你打算和别人分享这个项目,文件后台可能不是一个好的起点。Pulumi 还可以将其状态存储在 AWS S3 等云对象存储中。要使用它,请创建一个 S3 bucket 并登录:

pulumi login --cloud-url s3://my-pulumi-state-bucket

现在你已经登录到了状态后端,你可以创建一个项目和一个堆栈了!

在你开始创建 Pulumi 项目之前,请先了解以下 Pulumi 术语,你将在本教程中看到这些术语。

项目

项目 project 是一个包含 Pulumi.yaml 文件的目录。这个文件包含了 Pulumi 需要知道的元数据,以便进行它的工作。在 Pulumi.yaml 文件中可以找到的示例字段有:

  • 运行时(例如,Python、Node、Go、.Net)
  • 项目说明(如“我的第一个 Pulumi 项目”)
  • 项目名称

项目是一个松散的概念,可以满足你的需求。一般来说,一个项目包含了一系列的资源,这些资源是你想要提供和控制的东西。你可以选择拥有资源很少的小型 Pulumi 项目,也可以选择包含所有你需要的资源的大型项目。随着你对 Pulumi 越来越熟悉,你想如何布局你的项目会变得更加清晰。

堆栈

Pulumi 堆栈 stack 允许你根据可配置的值来区分你的 Pulumi 项目。一个常见的用途是将一个项目部署到不同的环境,如开发或生产环境,或不同的地区,如欧洲、中东和非洲以及美国。

在入门时,你不大需要一个复杂的堆栈设置,所以本演练使用默认的堆栈名称 dev

在 IaC 中使用 TypeScript

你可以使用方便的 pulumi new 命令来 初建 bootstrap 一个 Pulumi 项目。new 命令有一大堆标志和选项,可以帮助你入门 Pulumi,所以请继续创建你的第一个项目:

$ pulumi new typescript
This command will walk you through creating a new Pulumi project.

Enter a value or leave blank to accept the (default), and press <ENTER>.
Press ^C at any time to quit.

project name: (pulumi) my-first-project
project description: (A minimal TypeScript Pulumi program) My very first Pulumi program
Created project 'my-first-project'

Please enter your desired stack name.
To create a stack in an organization, use the format <org-name>/<stack-name> (e.g. `acmecorp/dev`).
stack name: (dev) dev
Created stack 'dev'

Installing dependencies...


> node scripts/postinstall

added 82 packages from 126 contributors and audited 82 packages in 2.84s

13 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Finished installing dependencies

Your new project is ready to go! ✨

To perform an initial deployment, run 'pulumi up'

这里发生了很多事情,我将其展开来说:

第一部分是为你的 Pulumi 项目确定一个模板。我选择了通用的 typescript 选项,但是有很多选项可供选择

这个 new 命令从你的模板库中抓取模板,并将这个文件复制到本地,包括运行时的依赖关系(在本例中是 package.json)。

new 命令通过在这个目录下运行 npm install 来安装这些依赖关系。然后 npm install 下载并安装运行 Pulumi 程序所需的一切,在这种情况下就是:@pulumi/pulumi NPM 包。

你已经准备好创建你的第一个资源了!

创建你的第一个云资源

资源是一个由你的基础设施供应软件生命周期进行管理的东西。资源一般是一个 云提供商对象 cloud provider object ,比如 S3 桶。Pulumi 的提供商处理 Pulumi 资源,提供商是具体的云提供商。Pulumi 有大约 40 个提供商可供你使用,但对于你的第一个资源,使用一个最简单的: 随机提供商 random provider

随机提供者顾名思义:它幂等地创建一个随机资源(例如,可以是一个字符串),并将其存储在 Pulumi 状态中。

使用 npm 将其添加到你的 Pulumi 项目中作为依赖关系:

npm install @pulumi/random

npm 包管理器下载并安装随机提供者包,并为你安装。现在你已经准备好编写你的 Pulumi 程序了。

当你之前生成你的项目时,Pulumi 的初建过程创建了一个 index.ts TypeScript 文件。在你喜欢的集成开发环境(IDE)中打开它,并添加你的第一个资源:

import * as pulumi from "@pulumi/pulumi";
import * as random from "@pulumi/random";

const password = new random.RandomString(`password`, {
    length: 10
})

如果你对 TypeScript 或 JavaScript 非常熟悉,这看起来会非常熟悉,因为它是用你熟悉的编程语言编写的。如果你使用的是 Pulumi 支持的其他语言之一,也是一样的。这里是之前的那个随机资源,但这次是用 Python 写的:

import pulumi_random as random

password = random.RandomString("password", length=10)

一个 Pulumi 项目目前只支持单一一种语言,但每个项目都可以引用其他语言编写的项目,这对于多语言团队的成员来说是一个很有用的技巧。

你已经编写了第一个 Pulumi 资源。现在你需要部署它。

离开编辑器,回到命令行。在你的项目目录下,运行 pulumi up,然后看着神奇的事情发生:

pulumi up

Previewing update (dev):
     Type                          Name                  Plan
 +   pulumi:pulumi:Stack           my-first-project-dev  create
 +   └─ random:index:RandomString  password              create

Resources:
    + 2 to create

Do you want to perform this update? yes
Updating (dev):
     Type                          Name                  Status
 +   pulumi:pulumi:Stack           my-first-project-dev  created
 +   └─ random:index:RandomString  password              created

Resources:
    + 2 created

Duration: 2s

Permalink: file:///Users/lbriggs/.pulumi/stacks/dev.json

太好了,你有了第一个 Pulumi 资源! 虽然你可能很享受这种成就感,但不幸的是,这个随机资源并没有那么有用:它只是一个随机的字符串,你甚至看不到它是什么。先解决这部分问题。修改你之前的程序,在你创建的常量中加入 export

import * as pulumi from "@pulumi/pulumi";
import * as random from "@pulumi/random";

export const password = new random.RandomString(`password`, {
    length: 10
})

重新运行 pulumi up,看看输出:

pulumi up
Previewing update (dev):
     Type                 Name                  Plan
     pulumi:pulumi:Stack  my-first-project-dev

Outputs:
  + password: {
      + id             : "&+r?{}J$J7"
      + keepers        : output<string>
      + length         : 10
      + lower          : true
      + minLower       : 0
      + minNumeric     : 0
      + minSpecial     : 0
      + minUpper       : 0
      + number         : true
      + overrideSpecial: output<string>
      + result         : "&+r?{}J$J7"
      + special        : true
      + upper          : true
      + urn            : "urn:pulumi:dev::my-first-project::random:index/randomString:RandomString::password"
    }

Resources:
    2 unchanged

Do you want to perform this update? yes
Updating (dev):
     Type                 Name                  Status
     pulumi:pulumi:Stack  my-first-project-dev

Outputs:
  + password: {
      + id        : "&+r?{}J$J7"
      + length    : 10
      + lower     : true
      + minLower  : 0
      + minNumeric: 0
      + minSpecial: 0
      + minUpper  : 0
      + number    : true
      + result    : "&+r?{}J$J7"
      + special   : true
      + upper     : true
      + urn       : "urn:pulumi:dev::my-first-project::random:index/randomString:RandomString::password"
    }

Resources:
    2 unchanged

Duration: 1s
Permalink: file:///Users/lbriggs/.pulumi/stacks/dev.json

现在你可以在 Outputsresult 部分下看到一个随机生成的字符串。你现在可以看到你创建的资源有很多属性。

这一切都很好,但如果你想享受 IaC,你得提供一些随机字符串以外的东西。试试吧。

部署一个容器

到目前为止,你已经通过安装依赖关系和注册一个简单的随机资源来 体验了初建你的 Pulumi。现在部署一些实际的基础设施,尽管是在你的本地机器上。

首先,将 @pulumi/docker 提供者添加到你的堆栈中。使用你选择的包管理器将其添加到项目中:

npm install @pulumi/docker

你已经从 npm 下拉了 Pulumi Docker 提供商包,这意味着你现在可以在你的项目中创建 Docker 镜像。

如果你的机器上还没有安装 Docker,现在是一个极好的时机去安装它。说明将取决于你的操作系统,所以看看 Docker 的安装页面了解信息。

再次打开你喜欢的 IDE,运行一个 Docker 容器。修改你之前的 index.ts 文件,让它看起来像这样:

import * as pulumi from "@pulumi/pulumi";
import * as random from "@pulumi/random";
import * as docker from "@pulumi/docker";

const password = new random.RandomString(`password`, {
    length: 10
})

const container = new docker.Container(`my-password`, {
    image: 'hashicorp/http-echo',
    command: [ pulumi.interpolate`-text=Your super secret password is: ${password.result}` ],
    ports: [{
        internal: 5678,
        external: 5678,
    }]
})

export const id = container.id

这将创建一个容器,创建一个 Web 服务器。Web 服务器的输出是你随机生成的字符串,在本例中是一个密码。运行这个,看看会发生什么:

pulumi up

Previewing update (dev):
     Type                       Name                  Plan
     pulumi:pulumi:Stack        my-first-project-dev
 +   └─ docker:index:Container  my-password           create

Outputs:
  + id      : output<string>
  ~ password: {
        id        : "&+r?{}J$J7"
        length    : 10
        lower     : true
        minLower  : 0
        minNumeric: 0
        minSpecial: 0
        minUpper  : 0
        number    : true
        result    : "&+r?{}J$J7"
        special   : true
        upper     : true
        urn       : "urn:pulumi:dev::my-first-project::random:index/randomString:RandomString::password"
    }

Resources:
    + 1 to create
    2 unchanged

Do you want to perform this update? yes
Updating (dev):
     Type                       Name                  Status
     pulumi:pulumi:Stack        my-first-project-dev
 +   └─ docker:index:Container  my-password           created

Outputs:
  + id      : "e73b34aeca34a64b72b61b0b9b8438637ce28853937bc359a1528ca99f49ddda"
    password: {
        id        : "&+r?{}J$J7"
        length    : 10
        lower     : true
        minLower  : 0
        minNumeric: 0
        minSpecial: 0
        minUpper  : 0
        number    : true
        result    : "&+r?{}J$J7"
        special   : true
        upper     : true
        urn       : "urn:pulumi:dev::my-first-project::random:index/randomString:RandomString::password"
    }

Resources:
    + 1 created
    2 unchanged

Duration: 2s
Permalink: file:///Users/lbriggs/.pulumi/stacks/dev.json

你会注意到在 Outputs 部分,你输出的值已经改变了,它只是一个 Docker 容器 ID。检查你的非常简单的密码生成器是否工作:

curl http://localhost:5678
Your super secret password is: &+r?{}J$J7

就是这样! 你刚刚用 TypeScript 配置了你的第一个基础架构。

关于 Pulumi 输出的快速说明

你会注意到在创建 Docker 容器的代码中,它使用了一个特殊的 pulumi.interpolate 调用。如果你熟悉 TypeScript,你可能会好奇为什么需要这样做(因为它是 Pulumi 特有的)。这有一个有趣的原因。

当 Pulumi 创建一个资源时,直到程序执行时有一些值是 Pulumi 不知道的。在 Pulumi 中,这些值被称为 Outputs。这些 Outputs 可以在上面的代码中看到,例如,在你的第一个随机资源中,你使用 export 关键字来输出随机资源的属性,你还输出了你创建的容器的容器 ID。

因为 Pulumi 直到执行时才知道这些 Outputs 的值,所以在操作字符串时,它需要特殊的助手来使用它们。如果你想了解更多关于这个特殊的编程模型,请观看这个短视频

总结

随着混合云基础架构中出现的复杂性,IaC 在很多方面都有了发展。在基础设施供应领域,Pulumi 是一个很好的选择,它可以使用你最喜欢的编程语言来供应你所需要的一切基础设施,然后你可以在你最喜欢的配置管理工具中进行标记,以采取下一步措施。


via: https://opensource.com/article/20/8/infrastructure-as-code-pulumi

作者:Lee Briggs 选题:lujun9972 译者:wxy 校对:wxy

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

许多计算机使用 网络时间协议 Network Time Protocol (NTP)通过互联网来同步系统时钟。NTP 是少数几个仍在普遍使用的不安全的互联网协议之一。攻击者如果能够观察到客户端和服务器之间的网络流量,就可以向客户端提供虚假的数据,并根据客户端的实现和配置,强迫其将系统时钟设置为任何时间和日期。如果客户端的系统时钟不准确,一些程序和服务就可能无法工作。例如,如果根据客户端的系统时钟,Web 服务器的证书似乎已经过期,Web 浏览器将无法正常工作。可以使用 网络时间安全 Network Time Security (NTS)来保证 NTP 的安全。

Fedora 33 [1] 是第一个支持 NTS 的 Fedora 版本。NTS 是一种新的 NTP 验证机制。它使客户端能够验证它们从服务器接收的数据包在传输过程中有没有被修改。当 NTS 启用时,攻击者唯一能做的就是丢弃或延迟数据包。关于 NTS 的更多细节,请参见 RFC8915

使用对称密钥可以很好地保证 NTP 的安全。遗憾的是,服务器必须为每个客户端配备不同的密钥,而且密钥必须安全地分发才行。这对于本地网络上的私有服务器来说可能是实用的,但它不能扩展到有着数百万客户端的公共服务器上。

NTS 包括一个 密钥建立 Key Establishment (NTS-KE)协议,它可以自动创建服务器与其客户端之间使用的加密密钥。它在 TCP 端口 4460 上使用 传输层安全 Transport Layer Security (TLS)。它被设计成可以扩展到非常多的客户端,而对准确性的影响最小。服务器不需要保存任何客户端特定的状态。它为客户提供 cookie,cookie 是加密的,包含验证 NTP 数据包所需的密钥。隐私是 NTS 的目标之一。客户端在每次服务器响应时都会得到一个新的 cookie,所以它不必重复使用 cookie。这可以防止被动观察者跟踪在网络之间迁移的客户端。

Fedora 中默认的 NTP 客户端是 Chrony。Chrony 在 4.0 版本中增加了 NTS 支持,但并没有改变默认配置。Chrony 仍然使用 pool.ntp.org 项目中的公共服务器,而且默认情况下 NTS 没有启用。

目前,支持 NTS 的公共 NTP 服务器非常少。两个主要的提供商是 Cloudflare 和 Netnod。Cloudflare 服务器分布在世界各地的不同地方。他们使用的是 任播 anycast 地址,应该可以让大多数客户到达一个接近的服务器。Netnod 服务器位于瑞典。在未来,我们可能会看到更多支持 NTS 的公共 NTP 服务器。

为了获得最佳的可靠性,配置 NTP 客户端的一般建议是至少有三个工作的服务器。为了达到最好的精度,建议选择距离较近的服务器,以减少网络延迟和非对称网络路由造成的不对称性。如果你不关心细粒度的精度,你可以忽略这个建议,使用任何你信任的 NTS 服务器,无论它们位于哪里。

如果你确实想要高准确度,但又没有近距离的 NTS 服务器,你可以将远处的 NTS 服务器和近处的非 NTS 服务器混合使用。但是,这样的配置不如只使用 NTS 服务器的配置安全。攻击者仍然不能强迫客户机接受任意时间,但他们确实对客户机的时钟及其估计精度有更大的控制权,这在某些环境下可能是不可接受的。

在安装程序中启用客户端 NTS

安装 Fedora 33 时,你可以在“Time & Date”对话框的“Network Time”配置中启用 NTS。在点击“+”(添加)按钮之前,请输入服务器的名称并检查 NTS 支持情况。你可以添加一个或多个具有 NTS 的服务器或池。要删除默认的服务器池(2.fedora.pool.ntp.org),请取消选中“Use”列中的相应标记。

Fedora 安装程序中的网络时间配置

在配置文件中启用客户端 NTS

如果你从之前的 Fedora 版本升级,或者你没有在安装程序中启用 NTS,你可以直接在 /etc/chrony.conf 中启用 NTS。除了推荐的 iburst 选项外,还可以对指定服务器使用 nts 选项。例如:

server time.cloudflare.com iburst nts
server nts.sth1.ntp.se iburst nts
server nts.sth2.ntp.se iburst nts

你还应该允许客户端将 NTS 密钥和 cookie 保存到磁盘上,这样它就不必在每次启动时重复 NTS-KE 会话。在 chrony.conf 中添加以下一行,如果还没有的话:

ntsdumpdir /var/lib/chrony

如果不想让 DHCP 提供的 NTP 服务器与你指定的服务器混在一起,请在 chrony.conf 中删除或注释以下一行:

sourcedir /run/chrony-dhcp

当你完成编辑 chrony.conf 后,保存你的更改并重新启动 chronyd 服务:

systemctl restart chronyd

检查客户端状态

在 root 用户下运行以下命令,检查 NTS 密钥建立是否成功:

# chronyc -N authdata
Name/IP address             Mode KeyID Type KLen Last Atmp  NAK Cook CLen
=========================================================================
time.cloudflare.com          NTS     1   15  256  33m    0    0    8  100
nts.sth1.ntp.se              NTS     1   15  256  33m    0    0    8  100
nts.sth2.ntp.se              NTS     1   15  256  33m    0    0    8  100

KeyIDTypeKLen 列应该有非零值。如果它们为零,请检查系统日志中是否有来自 chronyd 的错误信息。一个可能的故障原因是防火墙阻止了客户端与服务器的 TCP 端口(端口 4460)的连接。

另一个可能的故障原因是由于客户机的时钟错误而导致证书无法验证。这是 NTS 的先有鸡还是先有蛋的问题。你可能需要手动修正日期或暂时禁用 NTS,以使 NTS 正常工作。如果你的电脑有实时时钟,几乎所有的电脑都有,而且有好的电池做备份,这种操作应该只需要一次。

如果计算机没有实时时钟或电池,就像一些常见的小型 ARM 计算机(如树莓派)那样,你可以在 /etc/sysconfig/chronyd 中添加 -s 选项来恢复上次关机或重启时保存的时间。时钟会落后于真实时间,但如果电脑没有关机太久,服务器的证书也没有在离到期时间太近的时候更新,应该足以让时间检查成功。作为最后的手段,你可以用 nocerttimecheck 指令禁用时间检查。详情请参见chrony.conf(5) 手册页。

运行下面的命令来确认客户端是否在进行 NTP 测量:

# chronyc -N sources
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^* time.cloudflare.com           3   6   377    45   +355us[ +375us] +/-   11ms
^+ nts.sth1.ntp.se               1   6   377    44   +237us[ +237us] +/-   23ms
^+ nts.sth2.ntp.se               1   6   377    44   -170us[ -170us] +/-   22ms

Reach 列应该有一个非零值,最好是 377。上图所示的值 377 是一个八进制数,它表示最后八个请求都有有效的响应。如果启用了 NTS 的话,验证检查将包括 NTS 认证。如果该值一直很少或从未达到 377,则表明 NTP 请求或响应在网络中丢失了。众所周知,一些主要的网络运营商有中间设备,它可以阻止或限制大的 NTP 数据包的速率,以缓解利用 ntpd 的监控协议进行的放大攻击。不幸的是,这影响了受 NTS 保护的 NTP 数据包,尽管它们不会引起任何放大。NTP 工作组正在考虑为 NTP 提供一个替代端口,作为解决这个问题的办法。

在服务器上启用 NTS

如果你有自己的 NTP 服务器,运行着 chronyd,你可以启用服务器的 NTS 支持,让它的客户端安全同步。如果该服务器是其他服务器的客户端,它应该使用 NTS 或对称密钥与之同步。客户端假设同步链在所有服务器到主时间服务器之间是安全的。

启用服务器 NTS 类似于在 Web 服务器上启用 HTTPS。你只需要一个私钥和证书。例如,证书可以由 Let's Encrypt 权威机构使用 certbot 工具签署。当你有了密钥和证书文件(包括中间证书),在 chrony.conf 中用以下指令指定它们:

ntsserverkey /etc/pki/tls/private/foo.example.net.key
ntsservercert /etc/pki/tls/certs/foo.example.net.crt

确保之前在客户端配置中提到的 ntsdumpdir 指令存在于 chrony.conf 中。它允许服务器将其密钥保存到磁盘上,这样服务器的客户端在重启服务器时就不必获取新的密钥和 cookie 了。

重新启动 chronyd 服务:

systemctl restart chronyd

如果系统日志中没有来自 chronyd 的错误信息,那么它应该是可以接受客户端连接的,如果服务器有防火墙,则需要同时允许 UDP 123 和 TCP 4460 端口的 NTP 和 NTS-KE 服务。

你可以用下面的命令在客户端机器上进行快速测试:

$ chronyd -Q -t 3 'server foo.example.net iburst nts maxsamples 1'
2020-10-13T12:00:52Z chronyd version 4.0 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +NTS +SECHASH +IPV6 +DEBUG)
2020-10-13T12:00:52Z Disabled control of system clock
2020-10-13T12:00:55Z System clock wrong by -0.001032 seconds (ignored)
2020-10-13T12:00:55Z chronyd exiting

如果你看到一个“System clock wrong”消息,说明它是正确工作的。

在服务器上,你可以使用下面的命令来检查它已经处理了多少个 NTS-KE 连接和认证的 NTP 数据包:

# chronyc serverstats
NTP packets received       : 2143106240
NTP packets dropped        : 117180834
Command packets received   : 16819527
Command packets dropped    : 0
Client log records dropped : 574257223
NTS-KE connections accepted: 104
NTS-KE connections dropped : 0
Authenticated NTP packets  : 52139

如果你看到非零的 “NTS-KE connections accepted” 和 “Authenticated NTP packets”,这意味着至少有一些客户端能够连接到 NTS-KE 端口,并发送一个认证的 NTP 请求。

  1. Fedora 33 Beta 安装程序包含一个较旧的 Chrony 预发布版本,它不能与当前的 NTS 服务器一起工作,因为 NTS-KE 端口已经改变。因此,在安装程序中的网络时间配置中,服务器总是显示为不工作。安装后,需要更新 chrony 包,才能与当前的服务器配合使用。 ↩︎

via: https://fedoramagazine.org/secure-ntp-with-nts/

作者:Miroslav Lichvar 选题:lujun9972 译者:wxy 校对:wxy

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

容器化是一项蓬勃发展的技术。在不久的将来,多达百分之七十五的全球组织可能会运行某种类型的容器化技术。由于广泛使用的技术更容易成为黑客攻击的目标,因此保护容器的安全就显得尤为重要。本文将演示如何使用 POSIX 权能 Capability 来保护 Podman 容器的安全。Podman 是 RHEL8 中默认的容器管理工具。

确定 Podman 容器的权限模式

容器以特权模式或无特权模式运行。在特权模式下,容器的 uid 0 被映射到宿主机的 uid 0。对于某些情况,无特权的容器缺乏对宿主机资源的充分访问能力。但不管其操作模式如何,包括 强制访问控制 Mandatory Access Control (MAC:如 apparmor、SELinux 等)、seccomp 过滤器、删除 权能 Capability 、命名空间等在内的技术有助于确保容器的安全。

要从容器外部确定特权模式:

$ podman inspect --format="{{.HostConfig.Privileged}}" <container id>

如果上面的命令返回 true,那么容器在特权模式下运行。如果返回 false,那么容器在非特权模式下运行。

要从容器内部确定特权模式:

$ ip link add dummy0 type dummy

如果该命令允许你创建一个接口,那么你运行的是一个特权容器,否则你运行的是一个非特权容器。

权能

命名空间隔离了容器的进程,使其无法任意访问宿主机的资源,也无法访问在同一宿主机上运行的其他容器的资源。然而,在特权容器内的进程仍然可以做一些事情,如改变 IP 路由表、跟踪任意进程和加载内核模块。 权能 Capability 允许人们对容器内的进程可以访问或更改的资源施加更细微的限制,即使容器在特权模式下运行也一样。权能还允许人们为无特权的容器分配它本来不会拥有的特权。

例如,如果要将 NET_ADMIN 功能添加到一个无特权的容器中,以便在容器内部创建一个网络接口,你可以用下面的参数运行 podman

[root@vm1 ~]# podman run -it --cap-add=NET_ADMIN centos
[root@b27fea33ccf1 /]# ip link add dummy0 type dummy
[root@b27fea33ccf1 /]# ip link

上面的命令演示了在一个无特权的容器中创建一个 dummy0 接口。如果没有 NET_ADMIN 权能,非特权容器将无法创建接口。上面的命令演示了如何将一个权能授予一个无特权的容器。

目前,大约有 39 种权能可以被授予或拒绝。特权容器默认会被授予许多权能。建议从特权容器中删除不需要的权能,以使其更加安全。

要从容器中删除所有权能:

$ podman run -it -d --name mycontainer --cap-drop=all centos

列出一个容器的权能:

$ podman exec -it 48f11d9fa512 capsh --print

上述命令显示没有向容器授予任何权能。

请参考 capabilities 手册页以获取完整的权能列表:

$ man capabilities

可以使用 capsh 命令来列出目前拥有的权能:

$ capsh --print

作为另一个例子,下面的命令演示了如何从容器中删除 NET_RAW 权能。如果没有 NET_RAW 权能,就不能从容器中 ping 互联网上的服务器。

$ podman run -it --name mycontainer1 --cap-drop=net_raw centos
>>> ping google.com (will output error, operation not permitted)

最后一个例子,如果你的容器只需要 SETUIDSETGID 权能,你可以删除所有权能,然后只重新添加这两个权能来实现这样的权限设置。

$ podman run -d --cap-drop=all --cap-add=setuid --cap-add=setgid fedora sleep 5 > /dev/null; pscap | grep sleep

上面的 pscap 命令会显示容器被授予的权能。

我希望你喜欢这个关于如何使用权能来保护 Podman 容器的简短探索。

谢谢!


via: https://fedoramagazine.org/podman-with-capabilities-on-fedora/

作者:shiwanibiradar 选题:lujun9972 译者:geekpi 校对:wxy

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

LazPaint 是一款开源 Paint.NET 替代品,支持跨平台。它是一个轻量级的程序,拥有一堆快速编辑图像的基本选项。下面是 LazPaint 的概述。

LazPaint:Linux 下的开源 Paint.NET 替代品

如果你喜欢使用工具来快速编辑和处理图像和截图,你可能听说过 Paint.NET,但它只适用于 Windows 系统。

它是一个流行的小工具,可以完成很多基本的编辑任务,同时还有一堆可用的选项。你可能知道一些图像编辑工具,但 Paint.NET 是一个相当受欢迎的选择,因为对于一个普通用户来说,它易于使用,且没有任何臃肿的功能。

LazPaint 作为 Linux、Windows 和 macOS 上 Paint.NET 的令人印象深刻的开源替代品而出现。它提供了操作图像所需的大部分基本功能,同时又易于使用。

由于它是跨平台的应用,即使你不使用 Linux 系统,你仍然可以以自由开源工具使用它,这并非没有意义。现在,让我们看一下它提供的一些功能。

LazPaint 的功能

正如我前面提到的,LazPaint 提供了一堆必要的功能。在这里,我将列出关键的部分,这可以帮助你决定是否需要它。然而,我建议你去探索它,以了解更多关于它的信息。

  • 支持所有主要的文件格式(包括分层位图和 3D 文件)
  • 选区工具、裁剪选区、选区笔、反转选区
  • 支持导出到 Krita
  • 以各种质量设置对图像进行重新采样
  • 运动模糊、自定义模糊、径向模糊和像素化工具
  • 可以移除透明度和扁平化图像
  • 旋转和翻转图像
  • 将图像转换为负片
  • 能够调整画布的大小
  • 变形工具(透视)
  • 高级绘图工具
  • 设置工作区颜色
  • 黑暗主题
  • 支持脚本功能
  • 具有基本管理选项的层支持
  • 层效果
  • 过滤器
  • 灰度效果
  • 能够启用/禁用工具栏或将其添加到 Dock 上

在 Linux 上安装 LazPaint

你应该可以在你的官方软件仓库中找到它,通过你的默认软件包管理器来安装它,但要获得最新版本,你需要下载 .deb 文件,或者在非 Debian 的发行版上从源码编译它。

我希望有一个可以在每个 Linux 发行版上获得最新的版本的 Flatpak 软件包,但目前还没有。

它也适用于 Windows 和 macOS。你会发现 Windows 还有一个便携版,可以派上用场。

关于 LazPaint 的总结

我发现它真的很容易使用,以各种质量设置来重新采样(或调整大小)图像绝对是一个加分项。如果你已经安装了它,你一定注意到,它不需要大量的存储空间,总体上是一个轻量级的程序。

它的速度很快,我在快速测试中的大部分功能都相当好用,没有任何问题。

你觉得 LazPaint 作为 Paint.NET 的替代品怎么样?请在下面的评论中告诉我你的想法。


via: https://itsfoss.com/lazpaint/

作者:Ankush Das 选题:lujun9972 译者:geekpi 校对:wxy

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

Fedora 的默认网页浏览器是 Firefox。尽管它是一个优秀的网络浏览器,你可能更喜欢流行的 Google Chrome 浏览器。

如果你想知道如何在 Fedora 上安装 Google Chrome 浏览器,让我告诉你两种安装 Google Chrome 浏览器的方式:图形化方式和命令行方式。

这全取决于你喜欢哪种方式。你在 Fedora 上的 Google Chrome 浏览器都将通过这三种方式的系统更新获取定期更新。

方式 1:在 Fedora 中从软件中心安装 Google Chrome

Fedora 提供了一个第三方仓库,其中包含了一些流行的专有软件、图形驱动程序。Google Chrome 就是其中之一。

第一步,确保在 Fedora 中启用第三方仓库。你应该在软件中心中看到这个选项。

Step1: Fedora Third Party Repositories

启用后,只需在软件中心搜索 Chrome:

Step 2: Search for Chrome In Fedora Software Center

并从那里安装它:

Step 3: Install Chrome Fedora

还有比这更简单的吗?我觉得没有。

方式 2:在 Fedora 上从 Chrome 网站安装 Google Chrome

如果你不想启用第三方仓库,也没关系。你不必这样做。你可以从 Chrome 的网站上下载 RPM 文件,双击并安装它。

访问 Google Chrome 的网站,点击下载按钮。

然后选择 .rpm 包,点击“接受并安装”。

下载结束后,双击文件,在包管理器提示时点击安装。输入密码,等待安装完成。

这是超级简单的,对吧?让我们来看看有点复杂的方式(如果你不是一个终端爱好者)。

方式 3:使用命令行在 Fedora 上安装 Chrome

首先,你需要添加额外的 Fedora 仓库(你在方式 1 中看到的):

sudo dnf install fedora-workstation-repositories

然后启用 Google Chrome 仓库。

sudo dnf config-manager --set-enabled google-chrome

要安装 Google Chrome 稳定版,请在终端运行以下命令。

sudo dnf install google-chrome-stable

你会看到一个导入 GPG 密钥的警告,输入 y 继续。

你正在添加 Google Chrome 仓库。这个软件包来自这个仓库,它直接来自 Google。

总结

即使你使用命令行,在 Fedora 上安装 Google chrome 也相当简单。除了第三方仓库的部分,这和在 Ubuntu 上安装 Chrome 差不多。

现在你已经安装好了,你可能会想查看我们的 Google Chrome 键盘快捷键列表来更快地使用浏览器。


via: https://itsfoss.com/install-google-chrome-fedora/

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

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