用 Python 构建一个极小的区块链

虽然没接触过，但感觉像链表

# 用 Python 构建一个极小的区块链

虽然有些人认为区块链是一个早晚会出现问题的解决方案，但是毫无疑问，这个创新技术是一个计算机技术上的奇迹。那么，究竟什么是区块链呢？

### 区块链

>
> 以<ruby> 比特币 <rp>  （ </rp> <rt>  Bitcoin </rt> <rp>  ） </rp></ruby>或其它加密货币按时间顺序公开地记录交易的数字账本。
>
>
>

更通俗的说，它是一个公开的数据库，新的数据存储在被称之为<ruby> 区块 <rp>  （ </rp> <rt>  block </rt> <rp>  ） </rp></ruby>的容器中，并被添加到一个不可变的<ruby> 链 <rp>  （ </rp> <rt>  chain </rt> <rp>  ） </rp></ruby>中（因此被称为<ruby> 区块链 <rp>  （ </rp> <rt>  blockchain </rt> <rp>  ） </rp></ruby>），之前添加的数据也在该链中。对于比特币或其它加密货币来说，这些数据就是一组组交易，不过，也可以是其它任何类型的数据。

区块链技术带来了全新的、完全数字化的货币，如比特币和<ruby> 莱特币 <rp>  （ </rp> <rt>  Litecoin </rt> <rp>  ） </rp></ruby>，它们并不由任何中心机构管理。这给那些认为当今的银行系统是骗局并将最终走向失败的人带来了自由。区块链也革命性地改变了分布式计算的技术形式，如<ruby> 以太坊 <rp>  （ </rp> <rt>  Ethereum </rt> <rp>  ） </rp></ruby>就引入了一种有趣的概念：<ruby>   智能合约  <rp>  （ </rp> <rt>  smart contract </rt> <rp>  ） </rp></ruby>。

在这篇文章中，我将用不到 50 行的 Python 2.x 代码实现一个简单的区块链，我把它叫做 SnakeCoin。

### 不到 50 行代码的区块链

我们首先将从定义我们的区块是什么开始。在区块链中，每个区块随同时间戳及可选的索引一同存储。在 SnakeCoin 中，我们会存储这两者。为了确保整个区块链的完整性，每个区块都会有一个自识别的哈希值。如在比特币中，每个区块的哈希是该块的索引、时间戳、数据和前一个区块的哈希值等数据的加密哈希值。这里提及的“数据”可以是任何你想要的数据。

```
import hashlib as hasher

class Block:
  def __init__(self, index, timestamp, data, previous_hash):
    self.index = index
    self.timestamp = timestamp
    self.data = data
    self.previous_hash = previous_hash
    self.hash = self.hash_block()

  def hash_block(self):
    sha = hasher.sha256()
    sha.update(str(self.index) +
               str(self.timestamp) +
               str(self.data) +
               str(self.previous_hash))
    return sha.hexdigest()
```

真棒，现在我们有了区块的结构了，不过我们需要创建的是一个区块链。我们需要把区块添加到一个实际的链中。如我们之前提到过的，每个区块都需要前一个区块的信息。但问题是，该区块链中的第一个区块在哪里？好吧，这个第一个区块，也称之为创世区块，是一个特别的区块。在很多情况下，它是手工添加的，或通过独特的逻辑添加的。

我们将创建一个函数来简单地返回一个创世区块解决这个问题。这个区块的索引为 0 ，其包含一些任意的数据值，其“前一哈希值”参数也是任意值。

```
import datetime as date

def create_genesis_block():
  # Manually construct a block with
  # index zero and arbitrary previous hash
  return Block(0, date.datetime.now(), "Genesis Block", "0")
```

现在我们可以创建创世区块了，我们需要一个函数来生成该区块链中的后继区块。该函数将获取链中的前一个区块作为参数，为要生成的区块创建数据，并用相应的数据返回新的区块。新的区块的哈希值来自于之前的区块，这样每个新的区块都提升了该区块链的完整性。如果我们不这样做，外部参与者就很容易“改变过去”，把我们的链替换为他们的新链了。这个哈希链起到了加密的证明作用，并有助于确保一旦一个区块被添加到链中，就不能被替换或移除。

```
def next_block(last_block):
  this_index = last_block.index + 1
  this_timestamp = date.datetime.now()
  this_data = "Hey! I'm block " + str(this_index)
  this_hash = last_block.hash
  return Block(this_index, this_timestamp, this_data, this_hash)
```

这就是主要的部分。

现在我们能创建自己的区块链了！在这里，这个区块链是一个简单的 Python 列表。其第一个的元素是我们的创世区块，我们会添加后继区块。因为 SnakeCoin 是一个极小的区块链，我们仅仅添加了 20 个区块。我们通过循环来完成它。

```
# Create the blockchain and add the genesis block
blockchain = [create_genesis_block()]
previous_block = blockchain[0]

# How many blocks should we add to the chain
# after the genesis block
num_of_blocks_to_add = 20

# Add blocks to the chain
for i in range(0, num_of_blocks_to_add):
  block_to_add = next_block(previous_block)
  blockchain.append(block_to_add)
  previous_block = block_to_add
  # Tell everyone about it!
  print "Block #{} has been added to the blockchain!".format(block_to_add.index)
  print "Hash: {}\n".format(block_to_add.hash)
```

让我们看看我们的成果：

*别担心，它将一直添加到 20 个区块*

很好，我们的区块链可以工作了。如果你想要在主控台查看更多的信息，你可以编辑其[完整的源代码](https://gist.github.com/aunyks/8f2c2fd51cc17f342737917e1c2582e2)并输出每个区块的时间戳或数据。

这就是 SnakeCoin 所具有的功能。要使 SnakeCoin 达到现今的产品级的区块链的高度，我们需要添加更多的功能，如服务器层，以在多台机器上跟踪链的改变，并通过[工作量证明算法（POW）](https://en.bitcoin.it/wiki/Proof_of_work)来限制给定时间周期内可以添加的区块数量。

如果你想了解更多技术细节，你可以在[这里](https://bitcoin.org/bitcoin.pdf)查看最初的[比特币白皮书](https://bitcoin.org/bitcoin.pdf)。

### 让这个极小区块链稍微变大些

这个极小的区块链及其简单，自然也相对容易完成。但是因其简单也带来了一些缺陷。首先，SnakeCoin 仅能运行在单一的一台机器上，所以它相距分布式甚远，更别提去中心化了。其次，区块添加到区块链中的速度同在主机上创建一个 Python 对象并添加到列表中一样快。在我们的这个简单的区块链中，这不是问题，但是如果我们想让 SnakeCoin 成为一个实际的加密货币，我们就需要控制在给定时间内能创建的区块（和币）的数量。

从现在开始，SnakeCoin 中的“数据”将是交易数据，每个区块的“数据”字段都将是一些交易信息的列表。接着我们来定义“交易”。每个“交易”是一个 JSON 对象，其记录了币的发送者、接收者和转移的 SnakeCoin 数量。注：交易信息是 JSON 格式，原因我很快就会说明。

```
{
  "from": "71238uqirbfh894-random-public-key-a-alkjdflakjfewn204ij",
  "to": "93j4ivnqiopvh43-random-public-key-b-qjrgvnoeirbnferinfo",
  "amount": 3
}
```

现在我们知道了交易信息看起来的样子了，我们需要一个办法来将其加到我们的区块链网络中的一台计算机（称之为节点）中。要做这个事情，我们会创建一个简单的 HTTP 服务器，以便每个用户都可以让我们的节点知道发生了新的交易。节点可以接受 POST 请求，请求数据为如上的交易信息。这就是为什么交易信息是 JSON 格式的：我们需要它们可以放在请求信息中传递给服务器。

```
$ pip install flask # 首先安装 Web 服务器框架
```

```
from flask import Flask
from flask import request
node = Flask(__name__)

# Store the transactions that
# this node has in a list
this_nodes_transactions = []

@node.route('/txion', methods=['POST'])
def transaction():
  if request.method == 'POST':
    # On each new POST request,
    # we extract the transaction data
    new_txion = request.get_json()
    # Then we add the transaction to our list
    this_nodes_transactions.append(new_txion)
    # Because the transaction was successfully
    # submitted, we log it to our console
    print "New transaction"
    print "FROM: {}".format(new_txion['from'])
    print "TO: {}".format(new_txion['to'])
    print "AMOUNT: {}\n".format(new_txion['amount'])
    # Then we let the client know it worked out
    return "Transaction submission successful\n"

node.run()
```

真棒！现在我们有了一种保存用户彼此发送 SnakeCoin 的记录的方式。这就是为什么人们将区块链称之为公共的、分布式账本：所有的交易信息存储给所有人看，并被存储在该网络的每个节点上。

但是，有个问题：人们从哪里得到 SnakeCoin 呢？现在还没有办法得到，还没有一个称之为 SnakeCoin 这样的东西，因为我们还没有创建和分发任何一个币。要创建新的币，人们需要“挖”一个新的 SnakeCoin 区块。当他们成功地挖到了新区块，就会创建出一个新的 SnakeCoin ，并奖励给挖出该区块的人（矿工）。一旦挖矿的矿工将 SnakeCoin 发送给别人，这个币就流通起来了。

我们不想让挖新的 SnakeCoin 区块太容易，因为这将导致 SnakeCoin 太多了，其价值就变低了；同样，我们也不想让它变得太难，因为如果没有足够的币供每个人使用，它们对于我们来说就太昂贵了。为了控制挖新的 SnakeCoin 区块的难度，我们会实现一个<ruby>   工作量证明  <rp>  （ </rp> <rt>  Proof-of-Work </rt> <rp>  ） </rp></ruby>（PoW）算法。工作量证明基本上就是一个生成某个项目比较难，但是容易验证（其正确性）的算法。这个项目被称之为“证明”，听起来就像是它证明了计算机执行了特定的工作量。

在 SnakeCoin 中，我们创建了一个简单的 PoW 算法。要创建一个新区块，矿工的计算机需要递增一个数字，当该数字能被 9 （“SnakeCoin” 这个单词的字母数）整除时，这就是最后这个区块的证明数字，就会挖出一个新的 SnakeCoin 区块，而该矿工就会得到一个新的 SnakeCoin。

```
# ...blockchain
# ...Block class definition

miner_address = "q3nf394hjg-random-miner-address-34nf3i4nflkn3oi"

def proof_of_work(last_proof):
  # Create a variable that we will use to find
  # our next proof of work
  incrementor = last_proof + 1
  # Keep incrementing the incrementor until
  # it's equal to a number divisible by 9
  # and the proof of work of the previous
  # block in the chain
  while not (incrementor % 9 == 0 and incrementor % last_proof == 0):
    incrementor += 1
  # Once that number is found,
  # we can return it as a proof
  # of our work
  return incrementor

@node.route('/mine', methods = ['GET'])
def mine():
  # Get the last proof of work
  last_block = blockchain[len(blockchain) - 1]
  last_proof = last_block.data['proof-of-work']
  # Find the proof of work for
  # the current block being mined
  # Note: The program will hang here until a new
  #       proof of work is found
  proof = proof_of_work(last_proof)
  # Once we find a valid proof of work,
  # we know we can mine a block so
  # we reward the miner by adding a transaction
  this_nodes_transactions.append(
    { "from": "network", "to": miner_address, "amount": 1 }
  )
  # Now we can gather the data needed
  # to create the new block
  new_block_data = {
    "proof-of-work": proof,
    "transactions": list(this_nodes_transactions)
  }
  new_block_index = last_block.index + 1
  new_block_timestamp = this_timestamp = date.datetime.now()
  last_block_hash = last_block.hash
  # Empty transaction list
  this_nodes_transactions[:] = []
  # Now create the
  # new block!
  mined_block = Block(
    new_block_index,
    new_block_timestamp,
    new_block_data,
    last_block_hash
  )
  blockchain.append(mined_block)
  # Let the client know we mined a block
  return json.dumps({
      "index": new_block_index,
      "timestamp": str(new_block_timestamp),
      "data": new_block_data,
      "hash": last_block_hash
  }) + "\n"
```

现在，我们能控制特定的时间段内挖到的区块数量，并且我们给了网络中的人新的币，让他们彼此发送。但是如我们说的，我们只是在一台计算机上做的。如果区块链是去中心化的，我们怎样才能确保每个节点都有相同的链呢？要做到这一点，我们会使每个节点都广播其（保存的）链的版本，并允许它们接受其它节点的链。然后，每个节点会校验其它节点的链，以便网络中每个节点都能够达成最终的链的共识。这称之为<ruby>   共识算法  <rp>  （ </rp> <rt>  consensus algorithm </rt> <rp>  ） </rp></ruby>。

我们的共识算法很简单：如果一个节点的链与其它的节点的不同（例如有冲突），那么最长的链保留，更短的链会被删除。如果我们网络上的链没有了冲突，那么就可以继续了。

```
@node.route('/blocks', methods=['GET'])
def get_blocks():
  chain_to_send = blockchain
  # Convert our blocks into dictionaries
  # so we can send them as json objects later
  for block in chain_to_send:
    block_index = str(block.index)
    block_timestamp = str(block.timestamp)
    block_data = str(block.data)
    block_hash = block.hash
    block = {
      "index": block_index,
      "timestamp": block_timestamp,
      "data": block_data,
      "hash": block_hash
    }
  # Send our chain to whomever requested it
  chain_to_send = json.dumps(chain_to_send)
  return chain_to_send

def find_new_chains():
  # Get the blockchains of every
  # other node
  other_chains = []
  for node_url in peer_nodes:
    # Get their chains using a GET request
    block = requests.get(node_url + "/blocks").content
    # Convert the JSON object to a Python dictionary
    block = json.loads(block)
    # Add it to our list
    other_chains.append(block)
  return other_chains

def consensus():
  # Get the blocks from other nodes
  other_chains = find_new_chains()
  # If our chain isn't longest,
  # then we store the longest chain
  longest_chain = blockchain
  for chain in other_chains:
    if len(longest_chain) < len(chain):
      longest_chain = chain
  # If the longest chain wasn't ours,
  # then we set our chain to the longest
  blockchain = longest_chain
```

我们差不多就要完成了。在运行了[完整的 SnakeCoin 服务器代码](https://gist.github.com/aunyks/47d157f8bc7d1829a729c2a6a919c173)之后，在你的终端可以运行如下代码。（假设你已经安装了 cCUL）。

#### 1、创建交易

```
curl "localhost:5000/txion" \
     -H "Content-Type: application/json" \
     -d '{"from": "akjflw", "to":"fjlakdj", "amount": 3}'
```

#### 2、挖一个新区块

```
curl localhost:5000/mine
```

#### 3、 查看结果。从客户端窗口，我们可以看到。

对代码做下美化处理，我们看到挖矿后我们得到的新区块的信息：

```
{
  "index": 2,
  "data": {
    "transactions": [
      {
        "to": "fjlakdj",
        "amount": 3,
        "from": "akjflw"
      },
      {
        "to": "q3nf394hjg-random-miner-address-34nf3i4nflkn3oi",
        "amount": 1,
        "from": "network"
      }
    ],
    "proof-of-work": 36
  },
  "hash": "151edd3ef6af2e7eb8272245cb8ea91b4ecfc3e60af22d8518ef0bba8b4a6b18",
  "timestamp": "2017-07-23 11:23:10.140996"
}
```

大功告成！现在 SnakeCoin 可以运行在多个机器上，从而创建了一个网络，而且真实的 SnakeCoin 也能被挖到了。

你可以根据你的喜好去修改 SnakeCoin 服务器代码，并问各种问题了。

在下一篇（LCTT 译注：截止至本文翻译，作者还没有写出下一篇），我们将讨论创建一个 SnakeCoin 钱包，这样用户就可以发送、接收和存储他们的 SnakeCoin 了。


使用一个命令重置 Linux 桌面为默认设置

Summary: 如果你懒得安装 Resetter，你可以使用这个 dconf 命令在几分钟内将你的 Linux 系统重置为默认设置。

# 使用一个命令重置 Linux 桌面为默认设置

前段时间，我们分享了一篇关于 [Resetter](/article-9217-1.html) 的文章 —— 这是一个有用的软件，可以在几分钟内将 Ubuntu 重置为出厂默认设置。使用 Resetter，任何人都可以轻松地将 Ubuntu 重置为第一次安装时的状态。今天，我偶然发现了一个类似的东西。不，它不是一个应用程序，而是一个单行的命令来重置你的 Linux 桌面设置、调整和定制到默认状态。

### 将 Linux 桌面重置为默认设置

这个命令会将 Ubuntu Unity、Gnome 和 MATE 桌面重置为默认状态。我在我的 Arch Linux MATE 和 Ubuntu 16.04 Unity 上测试了这个命令。它可以在两个系统上工作。我希望它也能在其他桌面上运行。在写这篇文章的时候，我还没有安装 GNOME 的 Linux 桌面，因此我无法确认。但是，我相信它也可以在 Gnome 桌面环境中使用。

**一句忠告：**请注意，此命令将重置你在系统中所做的所有定制和调整，包括 Unity 启动器或 Dock 中固定的应用程序、桌面小程序、桌面指示器、系统字体、GTK主题、图标主题、显示器分辨率、键盘快捷键、窗口按钮位置、菜单和启动器行为等。

好的是它只会重置桌面设置。它不会影响其他不使用 `dconf` 的程序。此外，它不会删除你的个人资料。

现在，让我们开始。要将 Ubuntu Unity 或其他带有 GNOME/MATE 环境的 Linux 桌面重置，运行下面的命令：

```
dconf reset -f /

```

在运行上述命令之前，这是我的 Ubuntu 16.04 LTS 桌面：

[](http://www.ostechnix.com/wp-content/uploads/2017/10/Before-resetting-Ubuntu-to-default-1.png)

如你所见，我已经改变了桌面壁纸和主题。

这是运行该命令后，我的 Ubuntu 16.04 LTS 桌面的样子：

[](http://www.ostechnix.com/wp-content/uploads/2017/10/After-resetting-Ubuntu-to-default-1.png)

看见了么？现在，我的 Ubuntu 桌面已经回到了出厂设置。

有关 `dconf` 命令的更多详细信息，请参阅手册页。

```
man dconf

```

在重置桌面上我个人更喜欢 “Resetter” 而不是 `dconf` 命令。因为，Resetter 给用户提供了更多的选择。用户可以决定删除哪些应用程序、保留哪些应用程序、是保留现有用户帐户还是创建新用户等等。如果你懒得安装 Resetter，你可以使用这个 `dconf` 命令在几分钟内将你的 Linux 系统重置为默认设置。

就是这样了。希望这个有帮助。我将很快发布另一篇有用的指导。敬请关注！

干杯!

---

via: <https://www.ostechnix.com/reset-linux-desktop-default-settings-single-command/>

作者：[Edwin Arteaga](https://www.ostechnix.com) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


如何使用 yum-cron 自动更新 RHEL/CentOS Linux

Summary: 我知道如何使用 yum 命令行 更新系统，但是我想用 cron 任务自动更新软件包。

# 如何使用 yum-cron 自动更新 RHEL/CentOS Linux

`yum` 命令是 RHEL / CentOS Linux 系统中用来安装和更新软件包的一个工具。我知道如何使用 [yum 命令行](https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/) 更新系统，但是我想用 cron 任务自动更新软件包。该如何配置才能使得 `yum` 使用 [cron 自动更新](https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses)系统补丁或更新呢？

首先需要安装 yum-cron 软件包。该软件包提供以 cron 命令运行 `yum` 更新所需的文件。如果你想要每晚通过 cron 自动更新可以安装这个软件包。

### CentOS/RHEL 6.x/7.x 上安装 yum cron

输入以下 [yum 命令][3]:

```
$ sudo yum install yum-cron

```

使用 CentOS/RHEL 7.x 上的 `systemctl` 启动服务：

```
$ sudo systemctl enable yum-cron.service
$ sudo systemctl start yum-cron.service
$ sudo systemctl status yum-cron.service

```

在 CentOS/RHEL 6.x 系统中，运行：

```
$ sudo chkconfig yum-cron on
$ sudo service yum-cron start

```

`yum-cron` 是 `yum` 的一个替代方式。使得 cron 调用 `yum` 变得非常方便。该软件提供了元数据更新、更新检查、下载和安装等功能。`yum-cron` 的各种功能可以使用配置文件配置，而不是输入一堆复杂的命令行参数。

### 配置 yum-cron 自动更新 RHEL/CentOS Linux

使用 vi 等编辑器编辑文件 `/etc/yum/yum-cron.conf` 和 `/etc/yum/yum-cron-hourly.conf`：

```
$ sudo vi /etc/yum/yum-cron.conf

```

确保更新可用时自动更新：

```
apply_updates = yes

```

可以设置通知 email 的发件地址。注意： localhost`将会被`system\_name` 的值代替。

```
email_from = root@localhost

```

列出发送到的 email 地址。

```
email_to = your-it-support@some-domain-name

```

发送 email 信息的主机名。

```
email_host = localhost

```

[CentOS/RHEL 7.x][4] 上不想更新内核的话，添加以下内容：

```
exclude=kernel*

```

RHEL/CentOS 6.x 下[添加以下内容来禁用内核更新](https://www.cyberciti.biz/faq/redhat-centos-linux-yum-update-exclude-packages/)：

```
YUM_PARAMETER=kernel*

```

[保存并关闭文件](https://www.cyberciti.biz/faq/linux-unix-vim-save-and-quit-command/)。如果想每小时更新系统的话修改文件 `/etc/yum/yum-cron-hourly.conf`，否则文件 `/etc/yum/yum-cron.conf` 将使用以下命令每天运行一次（使用 [cat 命令](https://www.cyberciti.biz/faq/linux-unix-appleosx-bsd-cat-command-examples/) 查看）：

```
$ cat /etc/cron.daily/0yum-daily.cron

```

示例输出：

```
#!/bin/bash

# Only run if this flag is set. The flag is created by the yum-cron init
# script when the service is started -- this allows one to use chkconfig and
# the standard "service stop|start" commands to enable or disable yum-cron.
if [[ ! -f /var/lock/subsys/yum-cron ]]; then
 exit 0
fi

# Action!
exec /usr/sbin/yum-cron /etc/yum/yum-cron-hourly.conf
[root@centos7-box yum]# cat /etc/cron.daily/0yum-daily.cron
#!/bin/bash

# Only run if this flag is set. The flag is created by the yum-cron init
# script when the service is started -- this allows one to use chkconfig and
# the standard "service stop|start" commands to enable or disable yum-cron.
if [[ ! -f /var/lock/subsys/yum-cron ]]; then
 exit 0
fi

# Action!
exec /usr/sbin/yum-cron

```

完成配置。现在你的系统将每天自动更新一次。更多细节请参照 yum-cron 的说明手册。

```
$ man yum-cron

```

### 关于作者

作者是 nixCraft 的创始人，一个经验丰富的系统管理员和 Linux/Unix 脚本培训师。他曾与全球客户合作，领域涉及IT，教育，国防和空间研究以及非营利部门等多个行业。请在 [Twitter](https://twitter.com/nixcraft)、[Facebook](https://facebook.com/nixcraft)、[Google+](https://plus.google.com/+CybercitiBiz) 上关注他。获取更多有关系统管理、Linux/Unix 和开源话题请关注[我的 RSS/XML 地址](https://www.cyberciti.biz/atom/atom.xml)。

---

via: <https://www.cyberciti.biz/faq/fedora-automatic-update-retrieval-installation-with-cron/>

作者：[Vivek Gite](https://www.cyberciti.biz/) 译者：[shipsw](https://github.com/shipsw) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出

[3]:<https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/> [4]:<https://www.cyberciti.biz/faq/yum-update-except-kernel-package-command/>


RStudio IDE 入门

# RStudio IDE 入门

>
> 用于统计技术的 R 项目是分析数据的有力方式，而 RStudio IDE 则可使这一切更加容易。
>
>
>

从我记事起，我就一直喜欢摆弄数字。作为 20 世纪 70 年代后期的大学生，我上过统计学的课程，学习了如何检查和分析数据以揭示其意义。

那时候，我有一部科学计算器，它让统计计算变得比以往更容易。在 90 年代早期，作为一名从事 <ruby> t 检验 <rt>  t-test </rt></ruby>、相关性以及 [ANOVA](https://en.wikipedia.org/wiki/Analysis_of_variance) 研究的教育心理学研究生，我开始通过精心编写输入到 IBM 主机的文本文件来进行计算。这个主机远超我的手持计算器，但是一个小的空格错误就会导致整个过程无效，而且这个过程仍然有点乏味。

撰写论文时，尤其是我的毕业论文，我需要一种方法能够根据我的数据来创建图表，并将它们嵌入到文字处理文档中。我着迷于 Microsoft Excel 及其数字运算能力以及可以用计算结果创建出的大量图表。但这条路每一步都有成本。在 20 世纪 90 年代，除了 Excel，还有其他专有软件包，比如 SAS 和 SPSS+，但对于我那已经满满的研究生时间表来说，学习曲线是一项艰巨的任务。

### 快速回到现在

最近，由于我对数据科学的兴趣浓厚，加上对 Linux 和开源软件感兴趣，我阅读了大量的数据科学文章，并在 Linux 会议上听了许多数据科学演讲者谈论他们的工作。因此，我开始对编程语言 R（一种开源的统计计算软件）非常感兴趣。

起初，这只是一个偶发的一个想法。当我和我的朋友 Michael J. Gallagher 博士谈论他如何在他的 [博士论文](https://www.michael-j-gallagher.com/high-performance-computing) 研究中使用 R 时，这个火花便增大了。最后，我访问了 [R 项目](https://www.r-project.org/) 的网站，并了解到我可以轻松地安装 [R for Linux](https://cran.r-project.org/index.html)。游戏开始！

### 安装 R

根据你的操作系统和发行版情况，安装 R 会稍有不同。请参阅 [Comprehensive R Archive Network](https://cran.r-project.org/) （CRAN）网站上的安装指南。CRAN 提供了在 [各种 Linux 发行版](https://cran.r-project.org/bin/linux/)，[Fedora，RHEL，及其衍生版](https://cran.r-project.org/bin/linux/redhat/README)，[MacOS](https://cran.r-project.org/bin/macosx/) 和 [Windows](https://cran.r-project.org/bin/windows/) 上的安装指示。

我在使用 Ubuntu，按照 CRAN 的指示，将以下行加入到我的 `/etc/apt/sources.list` 文件中：

```
deb https://<my.favorite.cran.mirror>/bin/linux/ubuntu artful/

```

接着我在终端运行下面命令：

```
$ sudo apt-get update
$ sudo apt-get install r-base

```

根据 CRAN 说明，“需要从源码编译 R 的用户[如包的维护者，或者任何通过 `install.packages()` 安装包的用户]也应该安装 `r-base-dev` 的包。”

### 使用 R 和 RStudio

安装好了 R，我就准备了解更多关于使用这个强大的工具的信息。Gallagher 博士推荐了 [DataCamp](https://www.datacamp.com/onboarding/learn?from=home&technology=r) 上的 “R 语言入门”，并且我也在 [Code School](http://tryr.codeschool.com/levels/1/challenges/1) 找到了适用于 R 新手的免费课程。两门课程都帮助我学习了 R 的命令和语法。我还参加了 [Udemy](https://www.udemy.com/r-programming) 上的 R 在线编程课程，并从 [No Starch 出版社](https://opensource.com/article/17/10/no-starch) 上购买了 [R 之书](https://nostarch.com/bookofr)。

在阅读更多内容并观看 YouTube 视频后，我意识到我还应该安装 [RStudio](https://www.rstudio.com/)。Rstudio 是 R 语言的开源 IDE，易于在 [Debian、Ubuntu、 Fedora 和 RHEL](https://www.rstudio.com/products/rstudio/download/) 上安装。它也可以安装在 MacOS 和 Windows 上。

根据 RStudio 网站的说明，可以根据你的偏好对 IDE 进行自定义，具体方法是选择工具菜单，然后从中选择全局选项。

R 提供了一些很棒的演示例子，可以通过在提示符处输入 `demo()` 从控制台访问。`demo(plotmath)` 和 `demo(perspective)` 选项为 R 强大的功能提供了很好的例证。我尝试过一些简单的 [vectors](http://www.r-tutor.com/r-introduction/vector) 并在 R 控制台的命令行中绘制，如下所示。

你可能想要开始学习如何将 R 和一些样本数据结合起来使用，然后将这些知识应用到自己的数据上得到描述性统计。我自己没有丰富的数据来分析，但我搜索了可以使用的数据集 [datasets](https://vincentarelbundock.github.io/Rdatasets/datasets.html)；有一个这样的数据集（我并没有用这个例子）是由圣路易斯联邦储备银行提供的 [经济研究数据](https://fred.stlouisfed.org/)。我对一个题为“美国商业航空公司的乘客里程（1937-1960）”很感兴趣，因此我将它导入 RStudio 以测试 IDE 的功能。RStudio 可以接受各种格式的数据，包括 CSV、Excel、SPSS 和 SAS。

数据导入后，我使用 `summary(AirPassengers)` 命令获取数据的一些初始描述性统计信息。按回车键后，我得到了 1949-1960 年的每月航空公司旅客的摘要以及其他数据，包括飞机乘客数量的最小值、最大值、四分之一位数、四分之三位数、中位数以及平均数。

我从摘要统计信息中知道航空乘客样本的均值为 280.3。在命令行中输入 `sd(AirPassengers)` 会得到标准偏差，在 RStudio 控制台中可以看到：

接下来，我生成了一个数据直方图，通过输入 `hist(AirPassengers);` 得到，这会以图形的方式显示此数据集；RStudio 可以将数据导出为 PNG、PDF、JPEG、TIFF、SVG、EPS 或 BMP。

除了生成统计数据和图形数据外，R 还记录了我所有的历史操作。这使得我能够返回先前的操作，并且我可以保存此历史记录以供将来参考。

在 RStudio 的脚本编辑器中，我可以编写我发出的所有命令的脚本，然后保存该脚本以便在我的数据更改后能再次运行，或者想重新访问它。

### 获得帮助

在 R 提示符下输入 `help()` 可以很容易找到帮助信息。输入你正在寻找的信息的特定主题可以找到具体的帮助信息，例如 `help(sd)` 可以获得有关标准差的帮助。通过在提示符处输入 `contributors()` 可以获得有关 R 项目贡献者的信息。您可以通过在提示符处输入 `citation()` 来了解如何引用 R。通过在提示符出输入 `license()` 可以很容易地获得 R 的许可证信息。

R 是在 GNU General Public License（1991 年 6 月的版本 2，或者 2007 年 6 月的版本 3）的条款下发布的。有关 R 许可证的更多信息，请参考 [R 项目官网](https://www.r-project.org/Licenses/)。

另外，RStudio 在 GUI 中提供了完美的帮助菜单。该区域包括 RStudio 快捷表（可作为 PDF 下载），[RStudio](https://www.rstudio.com/online-learning/#R)的在线学习、RStudio 文档、支持和 [许可证信息](https://support.rstudio.com/hc/en-us/articles/217801078-What-license-is-RStudio-available-under-)。

---

via: <https://opensource.com/article/18/2/getting-started-RStudio-IDE>

作者：[Don Watkins](https://opensource.com/users/don-watkins) 译者：[szcf-weiya](https://github.com/szcf-weiya) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


du 及 df 命令的使用（附带示例）

Summary: du 和 df 命令都是 Linux 系统的重要工具，来显示 Linux 文件系统的磁盘使用情况。

# du 及 df 命令的使用（附带示例）

在本文中，我将讨论 `du` 和 `df` 命令。`du` 和 `df` 命令都是 Linux 系统的重要工具，来显示 Linux 文件系统的磁盘使用情况。这里我们将通过一些例子来分享这两个命令的用法。

* **（推荐阅读：[使用 scp 和 rsync 命令传输文件](http://linuxtechlab.com/files-transfer-scp-rsync-commands/)）**
* **（另请阅读：[使用 dd 和 cat 命令为 Linux 系统克隆磁盘](http://linuxtechlab.com/linux-cloning-disks-using-dd-cat-commands/)）**

### du 命令

`du`（disk usage 的简称）是用于查找文件和目录的磁盘使用情况的命令。`du` 命令在与各种选项一起使用时能以多种格式提供结果。

下面是一些例子：

#### 1、 得到一个目录下所有子目录的磁盘使用概况

```
$ du /home

```

该命令的输出将显示 `/home` 中的所有文件和目录以及显示块大小。

#### 2、 以人类可读格式也就是 kb、mb 等显示文件/目录大小

```
$ du -h /home

```

#### 3、 目录的总磁盘大小

```
$ du -s /home

```

它是 `/home` 目录的总大小

### df 命令

df（disk filesystem 的简称）用于显示 Linux 系统的磁盘利用率。（LCTT 译注：`df` 可能应该是 disk free 的简称。）

下面是一些例子。

#### 1、 显示设备名称、总块数、总磁盘空间、已用磁盘空间、可用磁盘空间和文件系统上的挂载点。

```
$ df

```

#### 2、 人类可读格式的信息

```
$ df -h

```

上面的命令以人类可读格式显示信息。

#### 3、 显示特定分区的信息

```
$ df -hT /etc

```

`-hT` 加上目标目录将以可读格式显示 `/etc` 的信息。

虽然 `du` 和 `df` 命令有更多选项，但是这些例子可以让你初步了解。如果在这里找不到你要找的东西，那么你可以参考有关命令的 man 页面。

另外，[**在这**](http://linuxtechlab.com/tips-tricks/)阅读我的其他帖子，在那里我分享了一些其他重要和经常使用的 Linux 命令。

如往常一样，欢迎你留下评论和疑问，因此在下面留下你的评论和疑问，我会回复你。

---

via: <http://linuxtechlab.com/du-df-commands-examples/>

作者：[SHUSAIN](http://linuxtechlab.com/author/shsuain/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Linux 新用户？来试试这 8 款重要的软件

# Linux 新用户？来试试这 8 款重要的软件

即便您不是计算机的新手，刚接触 Linux 时，通常都会面临选择使用应用软件的问题。在数百万 Linux 应用程序中，做起选择来并不轻松。本文中，您将能发现八个重要的 Linux 应用，帮助您快速选择应用程序。

下面这些应用程序大多不是 Linux 独有的。如果有过使用 Windows/Mac 的经验，您很可能会熟悉其中一些软件。根据兴趣和需求，下面的程序可能不全符合您的要求，但是在我看来，清单里大多数甚至全部的软件，对于新用户开启 Linux 之旅都是有帮助的。

**相关链接** : [每一个 Linux 用户都应该使用的 11 个可移植软件](https://www.maketecheasier.com/portable-apps-for-linux/ "11 Portable Apps Every Linux User Should Use")

### 1. Chromium 网页浏览器

几乎不会不需要使用网页浏览器的用户。您可以看到陈旧的 Linux 发行版几乎都会附带 Firefox（火狐浏览器）或者其他 [Linux 浏览器](https://www.maketecheasier.com/linux-browsers-you-probably-havent-heard-of/)，关于浏览器，强烈建议您尝试 [Chromium](http://www.chromium.org/)。它是谷歌浏览器的开源版。Chromium 的主要优点是速度和安全性。它同样拥有大量的附加组件。

### 2. LibreOffice

[LibreOffice](https://www.libreoffice.org/) 是一个开源办公套件，其包括文字处理（Writer）、电子表格（Calc）、演示（Impress）、数据库（Base）、公式编辑器（Math）、矢量图和流程图（Draw）应用程序。它与 Microsoft Office 文档兼容，如果其基本功能不能满足需求，您可以使用 [LibreOffice 拓展](https://www.maketecheasier.com/best-libreoffice-extensions/)。

LibreOffice 显然是 Linux 应用中至关重要的一员，如果您使用 Linux 的计算机，安装它是有必要的。

### 3. GIMP（<ruby> GUN 图像处理程序 <rt>  GNU Image Manipulation Program </rt></ruby>）

[GIMP](https://www.gimp.org/) 是一款非常强大的开源图片处理程序，它类似于 Photoshop。通过 GIMP，您可以编辑或是创建用于 Web 或是打印的光栅图（位图）。如果您对专业的图片处理没有概念，Linux 自然提供有更简单的图像编辑器，GIMP 看上去可能会复杂一点。GIMP 并不单纯提供图片裁剪和大小调整，它更覆盖了图层、滤镜、遮罩、路径和其他一些高级功能。

### 4. VLC 媒体播放器

[VLC](http://www.videolan.org/) 也许就是最好的影音播放器了。它是跨平台的，所以您可能在 Windows 上也听说过它。VLC 最特殊的地方是其拥有大量解码器（并不是所有的解码器都开放源代码），所以它几乎可以播放所有的影音文件。

### 5. Jitsy

[Jitsy](https://jitsi.org/) 完全是关于通讯的。您可以借助它使用 Google talk、Facebook chat、Yahoo、ICQ 和 XMPP。它是用于音视频通话（包括电话会议），<ruby> 桌面流 <rt>  desktop streaming </rt></ruby>和群组聊天的多用户工具。会话会被加密。Jistsy 同样能帮助您传输文件或记录电话。

### 6. Synaptic

[Synaptic](http://www.nongnu.org/synaptic/) 是一款基于 Debian 系统发行版的另一款应用程序安装程序。并不是所有基于 Debian 的 Linux 都安装有它，如果您使用基于 Debian 的 Linux 操作系统没有预装，也许您可以试一试。Synaptic 是一款用于添加或移除系统应用的 GUI 工具，甚至相对于许多发行版默认安装的 [软件中心包管理器](https://www.maketecheasier.com/are-linux-gui-software-centers-any-good/) ，经验丰富的 Linux 用户更亲睐于 Sunaptic。

**相关链接** : [10 款您没听说过的 Linux 生产力应用程序](https://www.maketecheasier.com/free-linux-productivity-apps-you-havent-heard-of/ "10 Free Linux Productivity Apps You Haven’t Heard Of")

### 7. VirtualBox

[VirtualBox](https://www.virtualbox.org/) 能支持您在计算机上运行虚拟机。当您想在当前 Linux 发行版上安装其他发行版或操作系统时，使用虚拟机会方便许多。您同样可以通过它运行 Windows 应用程序，性能可能会稍弱，但是如果您有一台强大的计算机，就不会那么糟。

### 8. AisleRiot Solitaire（纸牌游戏）

对于 Linux 的新用户来说，一款纸牌游戏并不是刚需，但是它真的太有趣了。当您进入这款纸牌游戏，您会发现，这是一款极好的纸牌游戏包。[AisleRiot](https://wiki.gnome.org/Aisleriot) 是 Linux 标志性的应用程序，原因是 - 它涵盖超过八十种纸牌游戏，包括流行的 Klondike、Bakers Dozen、Camelot 等等，作为预警 - 它是会上瘾的，您可能会花很长时间沉迷于此！

根据您所使用的发行版，这些软件会有不同的安装方法。但是大多数都可以通过您使用的发行版中的包管理器安装使用，甚至它们可能会预装在您的发行版上。安装并且尝试它们想必是最好的，如果不合您的胃口，您可以轻松地删除它们。

---

via: <https://www.maketecheasier.com/essential-linux-apps/>

作者：[Ada Ivanova](https://www.maketecheasier.com/author/adaivanoff/) 译者：[CYLeft](https://github.com/CYLeft) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


如何在 CentOS 7 / RHEL 7 终端服务器上安装 KVM

# 如何在 CentOS 7 / RHEL 7 终端服务器上安装 KVM

如何在 CnetOS 7 或 RHEL 7（Red Hat 企业版 Linux）服务器上安装和配置 KVM（基于内核的虚拟机）？如何在 CentOS 7 上设置 KVM 并使用云镜像 / cloud-init 来安装客户虚拟机？

基于内核的虚拟机（KVM）是 CentOS 或 RHEL 7 的虚拟化软件。KVM 可以将你的服务器变成虚拟机管理器。本文介绍如何在 CentOS 7 或 RHEL 7 中使用 KVM 设置和管理虚拟化环境。还介绍了如何使用命令行在物理服务器上安装和管理虚拟机（VM）。请确保在服务器的 BIOS 中启用了**虚拟化技术(VT)**。你也可以运行以下命令[测试 CPU 是否支持 Intel VT 和 AMD\_V 虚拟化技术](https://www.cyberciti.biz/faq/linux-xen-vmware-kvm-intel-vt-amd-v-support/)。

```
$ lscpu | grep Virtualization
Virtualization: VT-x

```

按照 CentOS 7/RHEL 7 终端服务器上的 KVM 安装步骤进行操作。

### 步骤 1： 安装 kvm

输入以下 [yum 命令](https://www.cyberciti.biz/faq/rhel-centos-fedora-linux-yum-command-howto/ "See Linux/Unix yum command examples for more info"):

```
# yum install qemu-kvm libvirt libvirt-python libguestfs-tools virt-install

```

[](https://www.cyberciti.biz/media/new/faq/2018/01/How-to-install-KVM-on-CentOS-7-RHEL-7-Headless-Server.jpg)

启动 libvirtd 服务：

```
# systemctl enable libvirtd
# systemctl start libvirtd

```

### 步骤 2： 确认 kvm 安装

使用 `lsmod` 命令和 [grep命令](https://www.cyberciti.biz/faq/howto-use-grep-command-in-linux-unix/ "See Linux/Unix grep command examples for more info") 确认加载了 KVM 模块：

```
# lsmod | grep -i kvm

```

### 步骤 3： 配置桥接网络

默认情况下，由 libvirtd 配置基于 dhcpd 的网桥。你可以使用以下命令验证：

```
# brctl show
# virsh net-list

```

[](https://www.cyberciti.biz/media/new/faq/2018/01/KVM-default-networking.jpg)

所有虚拟机（客户机）只能对同一台服务器上的其它虚拟机进行网络访问。为你创建的私有网络是 192.168.122.0/24。验证：

```
# virsh net-dumpxml default

```

如果你希望你的虚拟机可用于 LAN 上的其他服务器，请在连接到你的 LAN 的服务器上设置一个网桥。更新你的网卡配置文件，如 ifcfg-enp3s0 或 em1：

```
# vi /etc/sysconfig/network-scripts/ifcfg-enp3s0

```

添加一行：

```
BRIDGE=br0

```

[使用 vi 保存并关闭文件](https://www.cyberciti.biz/faq/linux-unix-vim-save-and-quit-command/)。编辑 `/etc/sysconfig/network-scripts/ifcfg-br0`：

```
# vi /etc/sysconfig/network-scripts/ifcfg-br0

```

添加以下内容：

```
DEVICE="br0"
# I am getting ip from DHCP server #
BOOTPROTO="dhcp"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
ONBOOT="yes"
TYPE="Bridge"
DELAY="0"

```

重新启动网络服务（警告：ssh 命令将断开连接，最好重新启动该设备）：

```
# systemctl restart NetworkManager

```

用 `brctl` 命令验证它：

```
# brctl show

```

### 步骤 4： 创建你的第一个虚拟机

我将会创建一个 CentOS 7.x 虚拟机。首先，使用 `wget` 命令获取 CentOS 7.x 最新的 ISO 镜像：

```
# cd /var/lib/libvirt/boot/
# wget https://mirrors.kernel.org/centos/7.4.1708/isos/x86_64/CentOS-7-x86_64-Minimal-1708.iso

```

验证 ISO 镜像：

```
# wget https://mirrors.kernel.org/centos/7.4.1708/isos/x86_64/sha256sum.txt
# sha256sum -c sha256sum.txt

```

#### 创建 CentOS 7.x 虚拟机

在这个例子中，我创建了 2GB RAM，2 个 CPU 核心，1 个网卡和 40 GB 磁盘空间的 CentOS 7.x 虚拟机，输入：

```
# virt-install \
--virt-type=kvm \
--name centos7 \
--ram 2048 \
--vcpus=1 \
--os-variant=centos7.0 \
--cdrom=/var/lib/libvirt/boot/CentOS-7-x86_64-Minimal-1708.iso \
--network=bridge=br0,model=virtio \
--graphics vnc \
--disk path=/var/lib/libvirt/images/centos7.qcow2,size=40,bus=virtio,format=qcow2

```

从另一个终端通过 `ssh` 配置 vnc 登录，输入：

```
# virsh dumpxml centos7 | grep v nc
<graphics type='vnc' port='5901' autoport='yes' listen='127.0.0.1'>

```

请记录下端口值（即 5901）。你需要使用 SSH 客户端来建立隧道和 VNC 客户端才能访问远程 vnc 服务器。在客户端/桌面/ macbook pro 系统中输入以下 SSH 端口转发命令：

```
$ ssh vivek@server1.cyberciti.biz -L 5901:127.0.0.1:5901

```

一旦你建立了 ssh 隧道，你可以将你的 VNC 客户端指向你自己的 127.0.0.1 (localhost) 地址和端口 5901，如下所示：

[](https://www.cyberciti.biz/media/new/faq/2016/01/vnc-client.jpg)

你应该看到 CentOS Linux 7 客户虚拟机安装屏幕如下：

[](https://www.cyberciti.biz/media/new/faq/2016/01/centos7-guest-vnc.jpg)

现在只需按照屏幕说明进行操作并安装CentOS 7。一旦安装完成后，请继续并单击重启按钮。 远程服务器关闭了我们的 VNC 客户端的连接。 你可以通过 KVM 客户端重新连接，以配置服务器的其余部分，包括基于 SSH 的会话或防火墙。

### 使用云镜像

以上安装方法对于学习目的或单个虚拟机而言是可行的。你需要部署大量的虚拟机吗？ 可以试试云镜像。你可以根据需要修改预先构建的云镜像。例如，使用 [Cloud-init](https://cloudinit.readthedocs.io/en/latest/index.html) 添加用户、ssh 密钥、设置时区等等，这是处理云实例的早期初始化的事实上的多分发包。让我们看看如何创建带有 1024MB RAM，20GB 磁盘空间和 1 个 vCPU 的 CentOS 7 虚拟机。（LCTT 译注： vCPU 即电脑中的虚拟处理器）

#### 获取 CentOS 7 云镜像

```
# cd /var/lib/libvirt/boot
# wget http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2

```

#### 创建所需的目录

```
# D=/var/lib/libvirt/images
# VM=centos7-vm1 ## vm name ##
# mkdir -vp $D/$VM
mkdir: created directory '/var/lib/libvirt/images/centos7-vm1'

```

#### 创建元数据文件

```
# cd $D/$VM
# vi meta-data

```

添加以下内容：

```
instance-id: centos7-vm1
local-hostname: centos7-vm1

```

#### 创建用户数据文件

我将使用 ssh 密钥登录到虚拟机。所以确保你有 ssh 密钥：

```
# ssh-keygen -t ed25519 -C "VM Login ssh key"

```

[](https://www.cyberciti.biz/faq/linux-unix-generating-ssh-keys/)

请参阅 “[如何在 Linux/Unix 系统上设置 SSH 密钥](https://www.cyberciti.biz/faq/how-to-set-up-ssh-keys-on-linux-unix/)” 来获取更多信息。编辑用户数据如下：

```
# cd $D/$VM
# vi user-data

```

添加如下（根据你的设置替换 `hostname`、`users`、`ssh-authorized-keys`）：

```
#cloud-config

# Hostname management
preserve_hostname: False
hostname: centos7-vm1
fqdn: centos7-vm1.nixcraft.com

# Users
users:
    - default
    - name: vivek
      groups: ['wheel']
      shell: /bin/bash
      sudo: ALL=(ALL) NOPASSWD:ALL
      ssh-authorized-keys:
        - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIMP3MOF2ot8MOdNXCpHem0e2Wemg4nNmL2Tio4Ik1JY VM Login ssh key

# Configure where output will go
output:
  all: ">> /var/log/cloud-init.log"

# configure interaction with ssh server
ssh_genkeytypes: ['ed25519', 'rsa']

# Install my public ssh key to the first user-defined user configured
# in cloud.cfg in the template (which is centos for CentOS cloud images)
ssh_authorized_keys:
  - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIMP3MOF2ot8MOdNXCpHem0e2Wemg4nNmL2Tio4Ik1JY VM Login ssh key

# set timezone for VM
timezone: Asia/Kolkata

# Remove cloud-init
runcmd:
  - systemctl stop network && systemctl start network
  - yum -y remove cloud-init

```

#### 复制云镜像

```
# cd $D/$VM
# cp /var/lib/libvirt/boot/CentOS-7-x86_64-GenericCloud.qcow2 $VM.qcow2

```

#### 创建 20GB 磁盘映像

```
# cd $D/$VM
# export LIBGUESTFS_BACKEND=direct
# qemu-img create -f qcow2 -o preallocation=metadata $VM.new.image 20G
# virt-resize --quiet --expand /dev/sda1 $VM.qcow2 $VM.new.image

```

[](https://www.cyberciti.biz/media/new/faq/2018/01/Set-VM-image-disk-size.jpg)

用缩放后的镜像覆盖它：

```
# cd $D/$VM
# mv $VM.new.image $VM.qcow2

```

#### 创建一个 cloud-init ISO

```
# mkisofs -o $VM-cidata.iso -V cidata -J -r user-data meta-data

```

[](https://www.cyberciti.biz/media/new/faq/2018/01/Creating-a-cloud-init-ISO.jpg)

#### 创建一个池

```
# virsh pool-create-as --name $VM --type dir --target $D/$VM
Pool centos7-vm1 created

```

#### 安装 CentOS 7 虚拟机

```
# cd $D/$VM
# virt-install --import --name $VM \
--memory 1024 --vcpus 1 --cpu host \
--disk $VM.qcow2,format=qcow2,bus=virtio \
--disk $VM-cidata.iso,device=cdrom \
--network bridge=virbr0,model=virtio \
--os-type=linux \
--os-variant=centos7.0 \
--graphics spice \
--noautoconsole

```

删除不需要的文件：

```
# cd $D/$VM
# virsh change-media $VM hda --eject --config
# rm meta-data user-data centos7-vm1-cidata.iso

```

#### 查找虚拟机的 IP 地址

```
# virsh net-dhcp-leases default

```

[](https://www.cyberciti.biz/media/new/faq/2018/01/CentOS7-VM1-Created.jpg)

#### 登录到你的虚拟机

使用 ssh 命令：

```
# ssh vivek@192.168.122.85

```

[](https://www.cyberciti.biz/media/new/faq/2018/01/Sample-VM-session.jpg)

### 有用的命令

让我们看看管理虚拟机的一些有用的命令。

#### 列出所有虚拟机

```
# virsh list --all

```

#### 获取虚拟机信息

```
# virsh dominfo vmName
# virsh dominfo centos7-vm1

```

#### 停止/关闭虚拟机

```
# virsh shutdown centos7-vm1

```

#### 开启虚拟机

```
# virsh start centos7-vm1

```

#### 将虚拟机标记为在引导时自动启动

```
# virsh autostart centos7-vm1

```

#### 重新启动（软安全重启）虚拟机

```
# virsh reboot centos7-vm1

```

重置（硬重置/不安全）虚拟机

```
# virsh reset centos7-vm1

```

#### 删除虚拟机

```
# virsh shutdown centos7-vm1
# virsh undefine centos7-vm1
# virsh pool-destroy centos7-vm1
# D=/var/lib/libvirt/images
# VM=centos7-vm1
# rm -ri $D/$VM

```

查看 virsh 命令类型的完整列表：

```
# virsh help | less
# virsh help | grep reboot

```

### 关于作者

作者是 nixCraft 的创建者，也是经验丰富的系统管理员和 Linux 操作系统/ Unix shell 脚本的培训师。 他曾与全球客户以及 IT，教育，国防和空间研究以及非营利部门等多个行业合作。 在 [Twitter](https://twitter.com/nixcraft)，[Facebook](https://facebook.com/nixcraft)，[Google +](https://plus.google.com/+CybercitiBiz) 上关注他。

---

via: <https://www.cyberciti.biz/faq/how-to-install-kvm-on-centos-7-rhel-7-headless-server/>

作者：[Vivek Gite](https://www.cyberciti.biz) 译者：[MjSeven](https://github.com/MjSeven) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


LKRG：用于运行时完整性检查的可加载内核模块

Summary: 开源社区的人们正在致力于一个 Linux 内核的新项目，它可以让内核更安全。命名为 Linux 内核运行时防护（Linux Kernel Runtime Guard，简称：LKRG），它是一个在 Linux 内核执行运行时完整性检查的可加载内核模块（LKM）。

# LKRG：用于运行时完整性检查的可加载内核模块

<img src="content_image/album_201803_18_233136pqcix692pvxcv92c.png" alt="LKRG logo" title="LKRG logo">

开源社区的人们正在致力于一个 Linux 内核的新项目，它可以让内核更安全。命名为 <ruby> Linux 内核运行时防护 <rp>  （ </rp> <rt>  Linux Kernel Runtime Guard </rt> <rp>  ） </rp></ruby>（LKRG），它是一个在 Linux 内核执行运行时完整性检查的可加载内核模块（LKM）。

它的用途是检测对 Linux 内核的已知的或未知的安全漏洞利用企图，以及去阻止这种攻击企图。

LKRG 也可以检测正在运行的进程的提权行为，在漏洞利用代码运行之前杀掉这个运行进程。

### 这个项目开发始于 2011 年，首个版本已经发布

因为这个项目开发的较早，LKRG 的当前版本仅仅是通过内核消息去报告违反内核完整性的行为，但是随着这个项目的成熟，将会部署一个完整的漏洞利用缓减系统。

LKRG 的成员 Alexander Peslyak 解释说，这个项目从 2011 年启动，并且 LKRG 已经经历了一个“重新开发"阶段。

LKRG 的首个公开版本是 LKRG v0.0，它现在可以从 [这个页面](http://www.openwall.com/lkrg/) 下载使用。[这里](http://openwall.info/wiki/p_lkrg/Main) 是这个项目的维基，为支持这个项目，它也有一个 [Patreon 页面](https://www.patreon.com/p_lkrg)。

虽然 LKRG 仍然是一个开源项目，LKRG 的维护者也计划做一个 LKRG Pro 版本，这个版本将包含一个专用的 LKRG 发行版，它将支持对特定漏洞利用的检测，比如，容器泄漏。开发团队计划从 LKRG Pro 基金中提取部分资金用于保证项目的剩余工作。

### LKRG 是一个内核模块而不是一个补丁。

一个类似的项目是<ruby> 附加内核监视器 <rt>  Additional Kernel Observer </rt></ruby>（AKO），但是 LKRG 与 AKO 是不一样的，因为 LKRG 是一个内核加载模块而不是一个补丁。LKRG 开发团队决定将它设计为一个内核模块是因为，在内核上打补丁对安全性、系统稳定性以及性能都有很直接的影响。

而以内核模块的方式提供，可以在每个系统上更容易部署 LKRG，而不必去修改核心的内核代码，修改核心的内核代码非常复杂并且很容易出错。

LKRG 内核模块在目前主流的 Linux 发行版上都可以使用，比如，RHEL7、OpenVZ 7、Virtuozzo 7、以及 Ubuntu 16.04 到最新的主线版本。

### 它并非是一个完美的解决方案

LKRG 的创建者警告用户，他们并不认为 LKRG 是一个完美的解决方案，它**提供不了**坚不可摧和 100% 的安全。他们说，LKRG 是 “设计为**可旁通**的”，并且仅仅提供了“多元化安全” 的**一个**方面。

>
> 虽然 LKRG 可以防御许多已有的 Linux 内核漏洞利用，而且也有可能会防御将来许多的（包括未知的）未特意设计去绕过 LKRG 的安全漏洞利用。它是设计为可旁通的（尽管有时候是以更复杂和/或低可利用为代价的）。因此，他们说 LKRG 通过多元化提供安全，就像运行一个不常见的操作系统内核一样，也就不会有真实运行一个不常见的操作系统的可用性弊端。
>
>
>

LKRG 有点像基于 Windows 的防病毒软件，它也是工作于内核级别去检测漏洞利用和恶意软件。但是，LKRG 团队说，他们的产品比防病毒软件以及其它终端安全软件更加安全，因为它的基础代码量比较小，所以在内核级别引入新 bug 和漏洞的可能性就更小。

### 运行当前版本的 LKRG 大约会带来 6.5% 的性能损失

Peslyak 说 LKRG 是非常适用于 Linux 机器的，它在修补内核的安全漏洞后不需要重启动机器。LKRG 允许用户持续运行带有安全措施的机器，直到在一个计划的维护窗口中测试和部署关键的安全补丁为止。

经测试显示，安装 LKRG v0.0 后大约会产生 6.5% 性能影响，但是，Peslyak 说将在后续的开发中持续降低这种影响。

测试也显示，LKRG 检测到了 CVE-2014-9322 (BadIRET)、CVE-2017-5123 (waitid(2) missing access\_ok)、以及 CVE-2017-6074 (use-after-free in DCCP protocol) 的漏洞利用企图，但是没有检测到 CVE-2016-5195 (Dirty COW) 的漏洞利用企图。开发团队说，由于前面提到的“可旁通”的设计策略，LKRG 没有检测到 Dirty COW 提权攻击。

>
> 在 Dirty COW 的测试案例中，由于 bug 机制的原因，使得 LKRG 发生了 “旁通”，并且这也是一种利用方法，它也是将来类似的以用户空间为目标的绕过 LKRG 的一种方法。这样的漏洞利用是否会是普通情况（不太可能！除非 LKRG 或者类似机制的软件流行起来），以及对它的可用性的（负面的）影响是什么？（对于那些直接目标是用户空间的内核漏洞来说，这不太重要，也并不简单）。
>
>
>

---

via: <https://www.bleepingcomputer.com/news/linux/lkrg-linux-to-get-a-loadable-kernel-module-for-runtime-integrity-checking/>

作者：[Catalin Cimpanu](https://www.bleepingcomputer.com/author/catalin-cimpanu/) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


在 Linux 上使用 NTP 保持精确的时间

# 在 Linux 上使用 NTP 保持精确的时间

<img src="content_image/album_201803_19_133828fjuejxe4geg4j2eg.jpg" alt="" title="">

如何保持正确的时间，如何使用 NTP 和 systemd 让你的计算机在不滥用时间服务器的前提下保持同步。

### 它的时间是多少？

让 Linux 来告诉你时间的时候，它是很奇怪的。你可能认为是使用 `time` 命令来告诉你时间，其实并不是，因为 `time` 只是一个测量一个进程运行了多少时间的计时器。为得到时间，你需要运行的是 `date` 命令，你想查看更多的日期，你可以运行 `cal` 命令。文件上的时间戳也是一个容易混淆的地方，因为根据你的发行版默认情况不同，它一般有两种不同的显示方法。下面是来自 Ubuntu 16.04 LTS 的示例：

```
$ ls -l
drwxrwxr-x 5 carla carla 4096 Mar 27 2017 stuff
drwxrwxr-x 2 carla carla 4096 Dec 8 11:32 things
-rw-rw-r-- 1 carla carla 626052 Nov 21 12:07 fatpdf.pdf
-rw-rw-r-- 1 carla carla 2781 Apr 18 2017 oddlots.txt

```

有些显示年，有些显示时间，这样的方式让你的文件更混乱。GNU 默认的情况是，如果你的文件在六个月以内，则显示时间而不是年。我想这样做可能是有原因的。如果你的 Linux 是这样的，尝试用 `ls -l --time-style=long-iso` 命令，让时间戳用同一种方式去显示，按字母顺序排序。请查阅 [如何更改 Linux 的日期和时间：简单的命令](https://www.linux.com/learn/how-change-linux-date-and-time-simple-commands) 去学习 Linux 上管理时间的各种方法。

### 检查当前设置

NTP —— 网络时间协议，它是保持计算机正确时间的老式方法。`ntpd` 是 NTP 守护程序，它通过周期性地查询公共时间服务器来按需调整你的计算机时间。它是一个简单的、轻量级的协议，使用它的基本功能时设置非常容易。systemd 通过使用 `systemd-timesyncd.service` 已经越俎代庖地 “干了 NTP 的活”，它可以用作 `ntpd` 的客户端。

在我们开始与 NTP “打交道” 之前，先花一些时间来了检查一下当前的时间设置是否正确。

你的系统上（至少）有两个时钟：系统时间 —— 它由 Linux 内核管理，第二个是你的主板上的硬件时钟，它也称为实时时钟（RTC）。当你进入系统的 BIOS 时，你可以看到你的硬件时钟的时间，你也可以去改变它的设置。当你安装一个新的 Linux 时，在一些图形化的时间管理器中，你会被询问是否设置你的 RTC 为 UTC（<ruby> 世界标准时间 <rt>  Coordinated Universal Time </rt></ruby>）时区，因为所有的时区和夏令时都是基于 UTC 的。你可以使用 `hwclock` 命令去检查：

```
$ sudo hwclock --debug
hwclock from util-linux 2.27.1
Using the /dev interface to the clock.
Hardware clock is on UTC time
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
...got clock tick
Time read from Hardware Clock: 2018/01/22 22:14:31
Hw clock time : 2018/01/22 22:14:31 = 1516659271 seconds since 1969
Time since last adjustment is 1516659271 seconds
Calculated Hardware Clock drift is 0.000000 seconds
Mon 22 Jan 2018 02:14:30 PM PST .202760 seconds

```

`Hardware clock is on UTC time` 表明了你的计算机的 RTC 是使用 UTC 时间的，虽然它把该时间转换为你的本地时间。如果它被设置为本地时间，它将显示 `Hardware clock is on local time`。

你应该有一个 `/etc/adjtime` 文件。如果没有的话，使用如下命令同步你的 RTC 为系统时间，

```
$ sudo hwclock -w

```

这个命令将生成该文件，内容看起来类似如下：

```
$ cat /etc/adjtime
0.000000 1516661953 0.000000
1516661953
UTC

```

新发明的 systemd 方式是去运行 `timedatectl` 命令，运行它不需要 root 权限：

```
$ timedatectl
 Local time: Mon 2018-01-22 14:17:51 PST
 Universal time: Mon 2018-01-22 22:17:51 UTC
 RTC time: Mon 2018-01-22 22:17:51
 Time zone: America/Los_Angeles (PST, -0800)
 Network time on: yes
NTP synchronized: yes
 RTC in local TZ: no

```

`RTC in local TZ: no` 表明它使用 UTC 时间。那么怎么改成使用本地时间？这里有许多种方法可以做到。最简单的方法是使用一个图形配置工具，比如像 openSUSE 中的 YaST。你也可使用 `timedatectl`：

```
$ timedatectl set-local-rtc 0

```

或者编辑 `/etc/adjtime`，将 `UTC` 替换为 `LOCAL`。

### systemd-timesyncd 客户端

现在，我已经累了，但是我们刚到非常精彩的部分。谁能想到计时如此复杂？我们甚至还没有了解到它的皮毛；阅读 `man 8 hwclock` 去了解你的计算机如何保持时间的详细内容。

systemd 提供了 `systemd-timesyncd.service` 客户端，它可以查询远程时间服务器并调整你的本地系统时间。在 `/etc/systemd/timesyncd.conf` 中配置你的（时间）服务器。大多数 Linux 发行版都提供了一个默认配置，它指向他们维护的时间服务器上，比如，以下是 Fedora 的：

```
[Time]
#NTP=
#FallbackNTP=0.fedora.pool.ntp.org 1.fedora.pool.ntp.org

```

你可以输入你希望使用的其它时间服务器，比如你自己的本地 NTP 服务器，在 `NTP=` 行上输入一个以空格分隔的服务器列表。（别忘了取消这一行的注释）`NTP=` 行上的任何内容都将覆盖掉 `FallbackNTP` 行上的配置项。

如果你不想使用 systemd 呢？那么，你将需要 NTP 就行。

### 配置 NTP 服务器和客户端

配置你自己的局域网 NTP 服务器是一个非常好的实践，这样你的网内计算机就不需要不停查询公共 NTP 服务器。在大多数 Linux 上的 NTP 都来自 `ntp` 包，它们大多都提供 `/etc/ntp.conf` 文件去配置时间服务器。查阅 [NTP 时间服务器池](http://support.ntp.org/bin/view/Servers/NTPPoolServers) 去找到你所在的区域的合适的 NTP 服务器池。然后在你的 `/etc/ntp.conf` 中输入 4 - 5 个服务器，每个服务器用单独的一行：

```
driftfile /var/ntp.drift
logfile /var/log/ntp.log
server 0.europe.pool.ntp.org
server 1.europe.pool.ntp.org
server 2.europe.pool.ntp.org
server 3.europe.pool.ntp.org

```

`driftfile` 告诉 `ntpd` 它需要保存用于启动时使用时间服务器快速同步你的系统时钟的信息。而日志也将保存在他们自己指定的目录中，而不是转储到 syslog 中。如果你的 Linux 发行版默认提供了这些文件，请使用它们。

现在去启动守护程序；在大多数主流的 Linux 中它的命令是 `sudo systemctl start ntpd`。让它运行几分钟之后，我们再次去检查它的状态：

```
$ ntpq -p
 remote refid st t when poll reach delay offset jitter
==============================================================
+dev.smatwebdesi 192.168.194.89 3 u 25 64 37 92.456 -6.395 18.530
*chl.la 127.67.113.92 2 u 23 64 37 75.175 8.820 8.230
+four0.fairy.mat 35.73.197.144 2 u 22 64 37 116.272 -10.033 40.151
-195.21.152.161 195.66.241.2 2 u 27 64 37 107.559 1.822 27.346

```

我不知道这些内容是什么意思，但重要的是，你的守护程序已经与时间服务器开始对话了，而这正是我们所需要的。你可以去运行 `sudo systemctl enable ntpd` 命令，永久启用它。如果你的 Linux 没有使用 systemd，那么，给你留下的家庭作业就是找出如何去运行 `ntpd`。

现在，你可以在你的局域网中的其它计算机上设置 `systemd-timesyncd`，这样它们就可以使用你的本地 NTP 服务器了，或者，在它们上面安装 NTP，然后在它们的 `/etc/ntp.conf` 上输入你的本地 NTP 服务器。

NTP 服务器会受到攻击，而且需求在不断增加。你可以通过运行你自己的公共 NTP 服务器来提供帮助。下周我们将学习如何运行你自己的公共服务器。

通过来自 Linux 基金会和 edX 的免费课程 [“Linux 入门”](https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux) 来学习更多 Linux 的知识。

---

via: <https://www.linux.com/learn/intro-to-linux/2018/1/keep-accurate-time-linux-ntp>

作者：[CARLA SCHRODER](https://www.linux.com/users/cschroder) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


我喜欢 Vue 的 10 个方面

# 我喜欢 Vue 的 10 个方面

<img src="content_image/album_201803_20_125546umz0h21hj3ojd0mm.jpg" alt="" title="">

我喜欢 Vue。当我在 2016 年第一次接触它时，也许那时我已经对 JavaScript 框架感到疲劳了，因为我已经具有Backbone、Angular、React 等框架的经验，没有太多的热情去尝试一个新的框架。直到我在 Hacker News 上读到一份评论，其描述 Vue 是类似于“新 jQuery” 的 JavaScript 框架，从而激发了我的好奇心。在那之前，我已经相当满意 React 这个框架，它是一个很好的框架，建立于可靠的设计原则之上，围绕着视图模板、虚拟 DOM 和状态响应等技术。而 Vue 也提供了这些重要的内容。

在这篇文章中，我旨在解释为什么 Vue 适合我，为什么在上文中那些我尝试过的框架中选择它。也许你将同意我的一些观点，但至少我希望能够给大家使用 Vue 开发现代 JavaScript 应用一些灵感。

### 1、 极少的模板语法

Vue 默认提供的视图模板语法是极小的、简洁的和可扩展的。像其他 Vue 部分一样，可以很简单的使用类似 JSX 一样语法，而不使用标准的模板语法（甚至有官方文档说明了如何做），但是我觉得没必要这么做。JSX 有好的方面，也有一些有依据的批评，如混淆了 JavaScript 和 HTML，使得很容易导致在模板中出现复杂的代码，而本来应该分开写在不同的地方的。

Vue 没有使用标准的 HTML 来编写视图模板，而是使用极少的模板语法来处理简单的事情，如基于视图数据迭代创建元素。

```
<template>
  <div id="app">
    <ul>
      <li v-for='number in numbers' :key='number'>{{ number }}</li>
    </ul>
    <form @submit.prevent='addNumber'>
      <input type='text' v-model='newNumber'>
      <button type='submit'>Add another number</button>
    </form>
  </div>
</template>

<script>
export default {
  name: 'app',
  methods: {
    addNumber() {
      const num = +this.newNumber;
      if (typeof num === 'number' && !isNaN(num)) {
        this.numbers.push(num);
      }
    }
  },
  data() {
    return {
      newNumber: null,
      numbers: [1, 23, 52, 46]
    };
  }
}
</script>

<style lang="scss">
ul {
  padding: 0;
  li {
    list-style-type: none;
    color: blue;
  }
}
</style>

```

我也喜欢 Vue 提供的简短绑定语法，`:` 用于在模板中绑定数据变量，`@` 用于绑定事件。这是一个细节，但写起来很爽而且能够让你的组件代码简洁。

### 2、 单文件组件

大多数人使用 Vue，都使用“单文件组件”。本质上就是一个 .vue 文件对应一个组件，其中包含三部分（CSS、HTML和JavaScript）。

这种技术结合是对的。它让人很容易在一个单独的地方了解每个组件，同时也非常好的鼓励了大家保持每个组件代码的简短。如果你的组件中 JavaScript、CSS 和 HTML 代码占了很多行，那么就到了进一步模块化的时刻了。

在使用 Vue 组件中的 `<style>` 标签时，我们可以添加 `scoped` 属性。这会让整个样式完全的封装到当前组件，意思是在组件中如果我们写了 `.name` 的 css 选择器，它不会把样式应用到其他组件中。我非常喜欢这种方式来应用样式而不是像其他主要框架流行在 JS 中编写 CSS 的方式。

关于单文件组件另一个好处是 .vue 文件实际上是一个有效的 HTML 5 文件。`<template>`、 `<script>`、 `<style>` 都是 w3c 官方规范的标签。这就表示很多如 linters （LCTT 译注：一种代码检查工具插件）这样我们用于开发过程中的工具能够开箱即用或者添加一些适配后使用。

### 3、 Vue “新的 jQuery”

事实上，这两个库不相似而且用于做不同的事。让我提供给你一个很精辟的类比（我实际上非常喜欢描述 Vue 和 jQuery 之间的关系）：披头士乐队和齐柏林飞船乐队（LCTT 译注：两个都是英国著名的乐队）。披头士乐队不需要介绍，他们是 20 世纪 60 年代最大的和最有影响力的乐队。但很难说披头士乐队是 20 世纪 70 年代最大的乐队，因为有时这个荣耀属于是齐柏林飞船乐队。你可以说两个乐队之间有着微妙的音乐联系或者说他们的音乐是明显不同的，但两者一些先前的艺术和影响力是不可否认的。也许 21 世纪初 JavaScript 的世界就像 20 世纪 70 年代的音乐世界一样，随着 Vue 获得更多关注使用，只会吸引更多粉丝。

一些使 jQuery 牛逼的哲学理念在 Vue 中也有呈现：非常容易的学习曲线但却具有基于现代 web 标准构建牛逼 web 应用所有你需要的功能。Vue 的核心本质上就是在 JavaScript 对象上包装了一层。

### 4、 极易扩展

正如前述，Vue 默认使用标准的 HTML、JS 和 CSS 构建组件，但可以很容易插入其他技术。如果我们想使用pug（LCTT译注：一款功能丰富的模板引擎，专门为 Node.js 平台开发）替换 HTML 或者使用 Typescript（LCTT译注：一种由微软开发的编程语言，是 JavaScript 的一个超集）替换 js 或者 Sass （LCTT 译注：一种 CSS 扩展语言）替换 CSS，只需要安装相关的 node 模块和在我们的单文件组件中添加一个属性到相关的标签即可。你甚至可以在一个项目中混合搭配使用 —— 如一些组件使用 HTML 其他使用 pug ——然而我不太确定这么做是最好的做法。

### 5、 虚拟 DOM

虚拟 DOM 是很好的技术，被用于现如今很多框架。其意味着这些框架能够做到根据我们状态的改变来高效的完成 DOM 更新，减少重新渲染，从而优化我们应用的性能。现如今每个框架都有虚拟 DOM 技术，所以虽然它不是什么独特的东西，但它仍然很出色。

### 6、 Vuex 很棒

对于大多数应用，管理状态成为一个棘手的问题，单独使用一个视图库不能解决这个问题。Vue 使用 Vuex 库来解决这个问题。Vuex 很容易构建而且和 Vue 集成的很好。熟悉 redux（另一个管理状态的库）的人学习 Vuex 会觉得轻车熟路，但是我发现 Vue 和 Vuex 集成起来更加简洁。最新 JavaScript 草案中（LCTT 译注：应该是指 ES7）提供了对象展开运算符（LCTT 译注：符号为 `...`），允许我们在状态或函数中进行合并，以操纵从 Vuex 到需要它的 Vue 组件中的状态。

### 7、 Vue 的命令行界面（CLI）

Vue 提供的命令行界面非常不错，很容易用 Vue 搭建一个基于 Webpack（LCTT 译注：一个前端资源加载/打包工具）的项目。单文件组件支持、babel（LCTT 译注：js 语法转换器）、linting（LCTT译注：代码检查工具）、测试工具支持，以及合理的项目结构，都可以在终端中一行命令创建。

然而有一个命令，我在 CLI 中没有找到，那就是 `vue build`。

>
> 如：
>
>
>
> ```
> echo '<template><h1>Hello World!</h1></template>' > Hello.vue && vue build Hello.vue -o
>
> ```
>
>

`vue build` 命令构建和运行组件并在浏览器中测试看起来非常简单。很不幸这个命令后来在 Vue 中删除了，现在推荐使用 Poi。Poi 本质上是在 Webpack 工具上封装了一层，但我不认我它像推特上说的那样简单。

### 8、 重新渲染优化

使用 Vue，你不必手动声明 DOM 的哪部分应该被重新渲染。我从来都不喜欢操纵 React 组件的渲染，像在`shouldComponentUpdate` 方法中停止整个 DOM 树重新渲染这种。Vue 在这方面非常巧妙。

### 9、 容易获得帮助

Vue 已经达到了使用这个框架来构建各种各样的应用的一种群聚效应。开发文档非常完善。如果你需要进一步的帮助，有多种渠道可用，每个渠道都有很多活跃开发者：stackoverflow、discord、twitter 等。相对于其他用户量少的框架，这就应该给你更多的信心来使用Vue构建应用。

### 10、 多机构维护

我认为，一个开源库，在发展方向方面的投票权利没有被单一机构操纵过多，是一个好事。就如同 React 的许可证问题（现已解决），Vue 就不可能涉及到。

总之，作为你接下来要开发的任何 JavaScript 项目，我认为 Vue 都是一个极好的选择。Vue 可用的生态圈比我博客中涉及到的其他库都要大。如果想要更全面的产品，你可以关注 Nuxt.js。如果你需要一些可重复使用的样式组件你可以关注类似 Vuetify 的库。

Vue 是 2017 年增长最快的库之一，我预测在 2018 年增长速度不会放缓。

如果你有空闲的 30 分钟，为什么不尝试下 Vue，看它可以给你提供什么呢？

P.S. — 这篇文档很好的展示了 Vue 和其他框架的比较：<https://vuejs.org/v2/guide/comparison.html>

---

via: <https://medium.com/@dalaidunc/10-things-i-love-about-vue-505886ddaff2>

作者：[Duncan Grant](https://medium.com/@dalaidunc) 译者：[yizhuoyan](https://github.com/yizhuoyan) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


使用 Zim 在你的 Linux 桌面上创建一个维基

Summary: 用强大而小巧的 Zim 在桌面上像维基一样管理信息。

确实是用过的最好用的桌面Wiki

用强大而小巧的 Zim 在桌面上像维基一样管理信息。

# 使用 Zim 在你的 Linux 桌面上创建一个维基

>
> 用强大而小巧的 Zim 在桌面上像维基一样管理信息。
>
>
>

不可否认<ruby> 维基 <rt>  wiki </rt></ruby>的用处，即使对于一个极客来说也是如此。你可以用它做很多事——写笔记和手稿，协作项目，建立完整的网站。还有更多的事。

这些年来，我已经使用了几个维基，要么是为了我自己的工作，要么就是为了我接到的各种合同和全职工作。虽然传统的维基很好，但我真的喜欢[桌面版维基](https://opensource.com/article/17/2/3-desktop-wikis) 这个想法。它们体积小，易于安装和维护，甚至更容易使用。而且，正如你可能猜到的那样，有许多可以用在 Linux 中的桌面版维基。

让我们来看看更好的桌面版的 维基 之一： [Zim](http://zim-wiki.org/)。

### 开始吧

你可以从 Zim 的官网[下载](http://zim-wiki.org/downloads.html)并安装 Zim，或者通过发行版的软件包管理器轻松地安装。

安装好了 Zim，就启动它。

在 Zim 中的一个关键概念是<ruby> 笔记本 <rt>  notebook </rt></ruby>，它们就像某个单一主题的维基页面的集合。当你第一次启动 Zim 时，它要求你为你的笔记本指定一个文件夹和笔记本的名称。Zim 建议用 `Notes` 来表示文件夹的名称和指定文件夹为 `~/Notebooks/`。如果你愿意，你可以改变它。我是这么做的。

在为笔记本设置好名称和指定好文件夹后，单击 “OK” 。你得到的本质上是你的维基页面的容器。

### 将页面添加到笔记本

所以你有了一个容器。那现在怎么办？你应该开始往里面添加页面。当然，为此，选择 “File > New Page”。

输入该页面的名称，然后单击 “OK”。从那里开始，你可以开始输入信息以向该页面添加信息。

这一页可以是你想要的任何内容：你正在选修的课程的笔记、一本书或者一片文章或论文的大纲，或者是你的书的清单。这取决于你。

Zim 有一些格式化的选项，其中包括：

* 标题
* 字符格式
* 圆点和编号清单
* 核对清单

你可以添加图片和附加文件到你的维基页面，甚至可以从文本文件中提取文本。

### Zim 的维基语法

你可以使用工具栏向一个页面添加格式。但这不是唯一的方法。如果你像我一样是个老派人士，你可以使用维基标记来进行格式化。

[Zim 的标记](http://zim-wiki.org/manual/Help/Wiki_Syntax.html) 是基于在 [DokuWiki](https://www.dokuwiki.org/wiki:syntax) 中使用的标记。它本质上是有一些小变化的 [WikiText](http://en.wikipedia.org/wiki/Wikilink) 。例如，要创建一个子弹列表，输入一个星号（`*`）。用两个星号包围一个单词或短语来使它加黑。

### 添加链接

如果你在笔记本上有一些页面，很容易将它们联系起来。有两种方法可以做到这一点。

第一种方法是使用 [驼峰命名法](https://en.wikipedia.org/wiki/Camel_case) 来命名这些页面。假设我有个叫做 “Course Notes” 的笔记本。我可以通过输入 “AnalysisCourse” 来重命名为我正在学习的数据分析课程。 当我想从笔记本的另一个页面链接到它时，我只需要输入 “AnalysisCourse” 然后按下空格键。即时超链接。

第二种方法是点击工具栏上的 “Insert link” 按钮。 在 “Link to” 中输入你想要链接到的页面的名称，从显示的列表中选择它，然后点击 “Link”。

我只能在同一个笔记本中的页面之间进行链接。每当我试图连接到另一个笔记本中的一个页面时，这个文件（有 .txt 的后缀名）总是在文本编辑器中被打开。

### 输出你的维基页面

也许有一天你会想在别的地方使用笔记本上的信息 —— 比如，在一份文件或网页上。你可以将笔记本页面导出到以下格式中的任何一种。而不是复制和粘贴（和丢失格式）：

* HTML
* LaTeX
* Markdown
* ReStructuredText

为此，点击你想要导出的维基页面。然后，选择 “File > Export”。决定是要导出整个笔记本还是一个页面，然后点击 “Forward”。

选择要用来保存页面或笔记本的文件格式。使用 HTML 和 LaTeX，你可以选择一个模板。 随便看看什么最适合你。 例如，如果你想把你的维基页面变成 HTML 演示幻灯片，你可以在 “Template” 中选择 “SlideShow s5”。 如果你想知道，这会产生由 [S5 幻灯片框架](https://meyerweb.com/eric/tools/s5/)驱动的幻灯片。

点击 “Forward”，如果你在导出一个笔记本，你可以选择将页面作为单个文件或一个文件导出。 你还可以指向要保存导出文件的文件夹。

### Zim 能做的就这些吗？

远远不止这些，还有一些 [插件](http://zim-wiki.org/manual/Plugins.html) 可以扩展它的功能。它甚至包含一个内置的 Web 服务器，可以让你将你的笔记本作为静态的 HTML 文件。这对于在内部网络上分享你的页面和笔记本是非常有用的。

总的来说，Zim 是一个用来管理你的信息的强大而又紧凑的工具。这是我使用过的最好的桌面版维基，而且我一直在使用它。

---

via: <https://opensource.com/article/18/2/create-wiki-your-linux-desktop-zim>

作者：[Scott Nesbitt](https://opensource.com/users/scottnesbitt) 译者：[Auk7F7](https://github.com/Auk7F7) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


初识 Python：Hello World 和字符串操作

Summary: 本文中的代码和视频可以在我的 GitHub 上找到。

本文中的代码和视频可以在我的 GitHub 上找到。

# 初识 Python：Hello World 和字符串操作

开始之前，说一下本文中的[代码](https://github.com/mGalarnyk/Python_Tutorials/blob/master/Python_Basics/Intro/Python3Basics_Part1.ipynb)和[视频](https://www.youtube.com/watch?v=JqGjkNzzU4s)可以在我的 GitHub 上找到。

那么，让我们开始吧！如果你糊涂了，我建议你在单独的选项卡中打开下面的视频。

* [Python 的 Hello World 和字符串操作视频](https://www.youtube.com/watch?v=JqGjkNzzU4s)

### 开始 (先决条件)

首先在你的操作系统上安装 Anaconda （Python）。你可以从[官方网站](https://www.continuum.io/downloads)下载 anaconda 并自行安装，或者你可以按照以下这些 anaconda 安装教程进行安装。

* 在 Windows 上安装 Anaconda： [链接[5](https://medium.com/@GalarnykMichael/install-python-on-windows-anaconda-c63c7c3d1444)
* 在 Mac 上安装 Anaconda： [链接](https://medium.com/@GalarnykMichael/install-python-on-mac-anaconda-ccd9f2014072)
* 在 Ubuntu (Linux) 上安装 Anaconda：[链接](https://medium.com/@GalarnykMichael/install-python-on-ubuntu-anaconda-65623042cb5a)

### 打开一个 Jupyter Notebook

打开你的终端（Mac）或命令行，并输入以下内容（[请参考视频中的 1:16 处](https://youtu.be/JqGjkNzzU4s?t=1m16s)）来打开 Jupyter Notebook：

```
jupyter notebook

```

### 打印语句/Hello World

在 Jupyter 的单元格中输入以下内容并按下 `shift + 回车`来执行代码。

```
# This is a one line comment
print('Hello World!')

```

*打印输出 “Hello World!”*

### 字符串和字符串操作

字符串是 Python 类的一种特殊类型。作为对象，在类中，你可以使用 `.methodName()` 来调用字符串对象的方法。字符串类在 Python 中默认是可用的，所以你不需要 `import` 语句来使用字符串对象接口。

```
# Create a variable
# Variables are used to store information to be referenced
# and manipulated in a computer program.
firstVariable = 'Hello World'
print(firstVariable)

```

*输出打印变量 firstVariable*

```
# Explore what various string methods
print(firstVariable.lower())
print(firstVariable.upper())
print(firstVariable.title())

```

*使用 .lower()、.upper() 和 title() 方法输出*

```
# Use the split method to convert your string into a list
print(firstVariable.split(' '))

```

*使用 split 方法输出（此例中以空格分隔）*

```
# You can add strings together.
a = "Fizz" + "Buzz"
print(a)

```

*字符串连接*

### 查询方法的功能

对于新程序员，他们经常问你如何知道每种方法的功能。Python 提供了两种方法来实现。

1、（在不在 Jupyter Notebook 中都可用）使用 `help` 查询每个方法的功能。

*查询每个方法的功能*

2.（Jupyter Notebook 专用）你也可以通过在方法之后添加问号来查找方法的功能。

```
# To look up what each method does in jupyter (doesnt work outside of jupyter)
firstVariable.lower?

```

*在 Jupyter 中查找每个方法的功能*

### 结束语

如果你对本文或在 [YouTube 视频](https://www.youtube.com/watch?v=JqGjkNzzU4s)的评论部分有任何疑问，请告诉我们。文章中的代码也可以在我的 [GitHub](https://github.com/mGalarnyk/Python_Tutorials/blob/master/Python_Basics/Intro/Python3Basics_Part1.ipynb) 上找到。本系列教程的第 2 部分是[简单的数学操作](https://medium.com/@GalarnykMichael/python-basics-2-simple-math-4ac7cc928738)。

---

via: <https://www.codementor.io/mgalarny/python-hello-world-and-string-manipulation-gdgwd8ymp>

作者：[Michael](https://www.codementor.io/mgalarny) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Ansible：像系统管理员一样思考的自动化框架

Summary: 直到我开始接触 Ansible，我才觉得这才是系统管理员喜欢的东西。

直到我开始接触 Ansible，我才觉得这才是系统管理员喜欢的东西。

# Ansible：像系统管理员一样思考的自动化框架

<img src="content_image/album_201803_21_224152x1eecp8p87qq676a.jpg" alt="" title="">

这些年来，我已经写了许多关于 DevOps 工具的文章，也培训了这方面的人员。尽管这些工具很棒，但很明显，大多数都是按照开发人员的思路设计出来的。这也没有什么问题，因为以编程的方式接近配置管理是重点。不过，直到我开始接触 Ansible，我才觉得这才是系统管理员喜欢的东西。

喜欢的一部分原因是 Ansible 与客户端计算机通信的方式，是通过 SSH 的。作为系统管理员，你们都非常熟悉通过 SSH 连接到计算机，所以从单词“去”的角度来看，相对于其它选择，你更容易理解 Ansible。

考虑到这一点，我打算写一些文章，探讨如何使用 Ansible。这是一个很好的系统，但是当我第一次接触到这个系统的时候，不知道如何开始。这并不是学习曲线陡峭。事实上，问题是在开始使用 Ansible 之前，我并没有太多的东西要学，这才是让人感到困惑的。例如，如果您不必安装客户端程序（Ansible 没有在客户端计算机上安装任何软件），那么您将如何启动？

### 踏出第一步

起初 Ansible 对我来说非常困难的原因在于配置服务器/客户端的关系是非常灵活的，我不知道我该从何入手。事实是，Ansible 并不关心你如何设置 SSH 系统。它会利用你现有的任何配置。需要考虑以下几件事情：

1. Ansible 需要通过 SSH 连接到客户端计算机。
2. 连接后，Ansible 需要提升权限才能配置系统，安装软件包等等。

不幸的是，这两个考虑真的带来了一堆蠕虫。连接到远程计算机并提升权限是一件可怕的事情。当您在远程计算机上安装代理并使用 Chef 或 Puppet 处理特权升级问题时，似乎感觉就没那么可怕了。 Ansible 并非不安全，而是安全的决定权在你手中。

接下来，我将列出一系列潜在的配置，以及每个配置的优缺点。这不是一个详尽的清单，但是你会受到正确的启发，去思考在你自己的环境中什么是理想的配置。也需要注意，我不会提到像 Vagrant 这样的系统，因为尽管 Vagrant 在构建测试和开发的敏捷架构时非常棒，但是和一堆服务器是非常不同的，因此考虑因素是极不相似的。

### 一些 SSH 场景

#### 1）在 Ansible 配置中，root 用户以密码进入远程计算机。

拥有这个想法是一个非常可怕的开始。这个设置的“优点”是它消除了对特权提升的需要，并且远程服务器上不需要其他用户帐户。 但是，这种便利的成本是不值得的。 首先，大多数系统不会让你在不改变默认配置的情况下以 root 身份进行 SSH 登录。默认的配置之所以如此，坦率地说，是因为允许 root 用户远程连接是一个不好的主意。 其次，将 root 密码放在 Ansible 机器上的纯文本配置文件中是不合适的。 真的，我提到了这种可能性，因为这是可以的，但这是应该避免的。 请记住，Ansible 允许你自己配置连接，它可以让你做真正愚蠢的事情。 但是请不要这么做。

#### 2）使用存储在 Ansible 配置中的密码，以普通用户的身份进入远程计算机。

这种情况的一个优点是它不需要太多的客户端配置。 大多数用户默认情况下都可以使用 SSH，因此 Ansible 应该能够使用用户凭据并且能够正常登录。 我个人不喜欢在配置文件中以纯文本形式存储密码，但至少它不是 root 密码。 如果您使用此方法，请务必考虑远程服务器上的权限提升方式。 我知道我还没有谈到权限提升，但是如果你在配置文件中配置了一个密码，这个密码可能会被用来获得 sudo 访问权限。 因此，一旦发生泄露，您不仅已经泄露了远程用户的帐户，还可能泄露整个系统。

#### 3）使用具有空密码的密钥对进行身份验证，以普通用户身份进入远程计算机。

这消除了将密码存储在配置文件中的弊端，至少在登录的过程中消除了。 没有密码的密钥对并不理想，但这是我经常做的事情。 在我的个人内部网络中，我通常使用没有密码的密钥对来自动执行许多事情，如需要身份验证的定时任务。 这不是最安全的选择，因为私钥泄露意味着可以无限制地访问远程用户的帐户，但是相对于在配置文件中存储密码我更喜欢这种方式。

#### 4）使用通过密码保护的密钥对进行身份验证，以普通用户的身份通过 SSH 连接到远程计算机。

这是处理远程访问的一种非常安全的方式，因为它需要两种不同的身份验证因素来解密：私钥和密码。 如果你只是以交互方式运行 Ansible，这可能是理想的设置。 当你运行命令时，Ansible 会提示你输入私钥的密码，然后使用密钥对登录到远程系统。 是的，只需使用标准密码登录并且不用在配置文件中指定密码即可完成，但是如果不管怎样都要在命令行上输入密码，那为什么不在保护层添加密钥对呢？

#### 5）使用密码保护密钥对进行 SSH 连接，但是使用 ssh-agent “解锁”私钥。

这并不能完美地解决无人值守、自动化的 Ansible 命令的问题，但是它确实也使安全设置变得相当方便。 ssh-agent 程序一次验证密码，然后使用该验证进行后续连接。当我使用 Ansible 时，这是我想要做的事情。如果我是完全值得信任的，我通常仍然使用没有密码的密钥对，但是这通常是因为我在我的家庭服务器上工作，是不是容易受到攻击的。

在配置 SSH 环境时还要记住一些其他注意事项。 也许你可以限制 Ansible 用户（通常是你的本地用户），以便它只能从一个特定的 IP 地址登录。 也许您的 Ansible 服务器可以位于不同的子网中，位于强大的防火墙之后，因此其私钥更难以远程访问。 也许 Ansible 服务器本身没有安装 SSH 服务器，所以根本没法访问。 同样，Ansible 的优势之一是它使用 SSH 协议进行通信，而且这是一个你用了多年的协议，你已经把你的系统调整到最适合你的环境了。 我不是宣传“最佳实践”的忠实粉丝，因为实际上最好的做法是考虑你的环境，并选择最适合你情况的设置。

### 权限提升

一旦您的 Ansible 服务器通过 SSH 连接到它的客户端，就需要能够提升特权。 如果你选择了上面的选项 1，那么你已经是 root 了，这是一个有争议的问题。 但是由于没有人选择选项 1（对吧？），您需要考虑客户端计算机上的普通用户如何获得访问权限。 Ansible 支持各种权限提升的系统，但在 Linux 中，最常用的选项是 `sudo` 和 `su`。 和 SSH 一样，有几种情况需要考虑，虽然肯定还有其他选择。

#### 1）使用 su 提升权限。

对于 RedHat/CentOS 用户来说，可能默认是使用 `su` 来获得系统访问权限。 默认情况下，这些系统在安装过程中配置了 root 密码，要想获得特殊访问权限，您需要输入该密码。使用 `su` 的问题在于，虽说它可以给了您完全访问远程系统，而您确实也可以完全访问远程系统。 （是的，这是讽刺。）另外，`su` 程序没有使用密钥对进行身份验证的能力，所以密码必须以交互方式输入或存储在配置文件中。 由于它实际上是 root 密码，因此将其存储在配置文件中听起来像、也确实是一个可怕的想法。

#### 2）使用 sudo 提升权限。

这就是 Debian/Ubuntu 系统的配置方式。 正常用户组中的用户可以使用 `sudo` 命令并使用 root 权限执行该命令。 随之而来的是，这仍然存在密码存储或交互式输入的问题。 由于在配置文件中存储用户的密码看起来不太可怕，我猜这是使用 `su` 的一个进步，但是如果密码被泄露，仍然可以完全访问系统。 （毕竟，输入 `sudo` 和 `su -` 都将允许用户成为 root 用户，就像拥有 root 密码一样。）

#### 3） 使用 sudo 提升权限，并在 sudoers 文件中配置 NOPASSWD。

再次，在我的本地环境中，我就是这么做的。 这并不完美，因为它给予用户帐户无限制的 root 权限，并且不需要任何密码。 但是，当我这样做并且使用没有密码短语的 SSH 密钥对时，我可以让 Ansible 命令更轻松的自动化。 再次提示，虽然这很方便，但这不是一个非常安全的想法。

#### 4）使用 sudo 提升权限，并在特定的可执行文件上配置 NOPASSWD。

这个想法可能是安全性和便利性的最佳折衷。 基本上，如果你知道你打算用 Ansible 做什么，那么你可以为远程用户使用的那些应用程序提供 NOPASSWD 权限。 这可能会让人有些困惑，因为 Ansible 使用 Python 来处理很多事情，但是经过足够的尝试和错误，你应该能够弄清原理。 这是额外的工作，但确实消除了一些明显的安全漏洞。

### 计划实施

一旦你决定如何处理 Ansible 认证和权限提升，就需要设置它。 在熟悉 Ansible 之后，您可能会使用该工具来帮助“引导”新客户端，但首先手动配置客户端非常重要，以便您知道发生了什么事情。 将你熟悉的事情变得自动化比从头开始自动化要好。

我已经写过关于 SSH 密钥对的文章，网上有无数的设置类的文章。 来自 Ansible 服务器的简短版本看起来像这样：

```
# ssh-keygen
# ssh-copy-id -i .ssh/id_dsa.pub remoteuser@remote.computer.ip
# ssh remoteuser@remote.computer.ip

```

如果您在创建密钥对时选择不使用密码，最后一步您应该可以直接进入远程计算机，而不用输入密码或密钥串。

为了在 `sudo` 中设置权限提升，您需要编辑 `sudoers` 文件。 你不应该直接编辑文件，而是使用：

```
# sudo visudo

```

这将打开 `sudoers` 文件并允许您安全地进行更改（保存时会进行错误检查，所以您不会意外地因为输入错误将自己锁住）。 这个文件中有一些例子，所以你应该能够弄清楚如何分配你想要的确切的权限。

一旦配置完成，您应该在使用 Ansible 之前进行手动测试。 尝试 SSH 到远程客户端，然后尝试使用您选择的任何方法提升权限。 一旦你确认配置的方式可以连接，就可以安装 Ansible 了。

### 安装 Ansible

由于 Ansible 程序仅安装在一台计算机上，因此开始并不是一件繁重的工作。 Red Hat/Ubuntu 系统的软件包安装有点不同，但都不是很困难。

在 Red Hat/CentOS 中，首先启用 EPEL 库：

```
sudo yum install epel-release

```

然后安装 Ansible：

```
sudo yum install ansible

```

在 Ubuntu 中，首先启用 Ansible PPA：

```
sudo apt-add-repository spa:ansible/ansible
(press ENTER to access the key and add the repo)

```

然后安装 Ansible：

```
sudo apt-get update
sudo apt-get install ansible

```

### Ansible 主机文件配置

Ansible 系统无法知道您希望它控制哪个客户端，除非您给它一个计算机列表。 该列表非常简单，看起来像这样：

```
# file /etc/ansible/hosts

[webservers]
blogserver ansible_host=192.168.1.5
wikiserver ansible_host=192.168.1.10

[dbservers]
mysql_1 ansible_host=192.168.1.22
pgsql_1 ansible_host=192.168.1.23

```

方括号内的部分是指定的组。 单个主机可以列在多个组中，而 Ansible 可以指向单个主机或组。 这也是配置文件，比如纯文本密码的东西将被存储，如果这是你计划的那种设置。 配置文件中的每一行配置一个主机地址，并且可以在 `ansible_host` 语句之后添加多个声明。 一些有用的选项是：

```
ansible_ssh_pass
ansible_become
ansible_become_method
ansible_become_user
ansible_become_pass

```

### Ansible <ruby> 保险库 <rt>  Vault </rt></ruby>

（LCTT 译注：Vault 作为 ansible 的一项新功能可将例如密码、密钥等敏感数据文件进行加密，而非明文存放）

我也应该注意到，尽管安装程序比较复杂，而且这不是在您首次进入 Ansible 世界时可能会做的事情，但该程序确实提供了一种加密保险库中的密码的方法。 一旦您熟悉 Ansible，并且希望将其投入生产，将这些密码存储在加密的 Ansible 保险库中是非常理想的。 但是本着先学会爬再学会走的精神，我建议首先在非生产环境下使用无密码方法。

### 系统测试

最后，你应该测试你的系统，以确保客户端可以正常连接。 `ping` 测试将确保 Ansible 计算机可以 `ping` 每个主机：

```
ansible -m ping all

```

运行后，如果 `ping` 成功，您应该看到每个定义的主机显示 `ping` 的消息：`pong`。 这实际上并没有测试认证，只是测试网络连接。 试试这个来测试你的认证：

```
ansible -m shell -a 'uptime' webservers

```

您应该可以看到 webservers 组中每个主机的运行时间命令的结果。

在后续文章中，我计划开始深入 Ansible 管理远程计算机的功能。 我将介绍各种模块，以及如何使用 ad-hoc 模式来完成一些按键操作，这些操作在命令行上单独处理都需要很长时间。 如果您没有从上面的示例 Ansible 命令中获得预期的结果，请花些时间确保身份验证可以工作。 如果遇到困难，请查阅 [Ansible 文档](http://docs.ansible.com)获取更多帮助。

---

via: <http://www.linuxjournal.com/content/ansible-automation-framework-thinks-sysadmin>

作者：[Shawn Powers](http://www.linuxjournal.com/users/shawn-powers) 译者：[Flowsnow](https://github.com/Flowsnow) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


如何使用 GNU Stow 来管理从源代码安装的程序和点文件

Summary: 有时候我们必须从源代码安装程序，因为它们也许不能通过标准渠道获得，或者我们可能需要特定版本的软件。 GNU Stow 是一个非常不错的符号链接工厂（symlinks factory）程序，它可以帮助我们保持文件的整洁，易于维护。

# 如何使用 GNU Stow 来管理从源代码安装的程序和点文件

<img src="content_image/album_201803_22_004447wj4b8s5s96kvu660.jpg" alt="" title="">

### 目的

使用 GNU Stow 轻松管理从源代码安装的程序和点文件（LCTT 译注：<ruby> 点文件 <rt>  dotfile </rt></ruby>，即以 `.` 开头的文件，在 \*nix 下默认为隐藏文件，常用于存储程序的配置信息。）

### 要求

* root 权限

### 难度

简单

### 约定

* `#` - 给定的命令要求直接以 root 用户身份或使用 `sudo` 命令以 root 权限执行
* `$` - 给定的命令将作为普通的非特权用户来执行

### 介绍

有时候我们必须从源代码安装程序，因为它们也许不能通过标准渠道获得，或者我们可能需要特定版本的软件。 GNU Stow 是一个非常不错的<ruby> 符号链接工厂 <rt>  symlinks factory </rt></ruby>程序，它可以帮助我们保持文件的整洁，易于维护。

### 获得 stow

你的 Linux 发行版本很可能包含 `stow`，例如在 Fedora，你安装它只需要：

```
# dnf install stow

```

在 Ubuntu/Debian 中，安装 `stow` 需要执行：

```
# apt install stow

```

在某些 Linux 发行版中，`stow` 在标准库中是不可用的，但是可以通过一些额外的软件源（例如 RHEL 和 CentOS7 中的EPEL ）轻松获得，或者，作为最后的手段，你可以从源代码编译它。只需要很少的依赖关系。

### 从源代码编译

最新的可用 stow 版本是 `2.2.2`。源码包可以在这里下载：`https://ftp.gnu.org/gnu/stow/`。

一旦你下载了源码包，你就必须解压它。切换到你下载软件包的目录，然后运行：

```
$ tar -xvpzf stow-2.2.2.tar.gz

```

解压源文件后，切换到 `stow-2.2.2` 目录中，然后编译该程序，只需运行:

```
$ ./configure
$ make

```

最后，安装软件包：

```
# make install

```

默认情况下，软件包将安装在 `/usr/local/` 目录中，但是我们可以改变它，通过配置脚本的 `--prefix` 选项指定目录，或者在运行 `make install` 时添加 `prefix="/your/dir"`。

此时，如果所有工作都按预期工作，我们应该已经在系统上安装了 `stow`。

### stow 是如何工作的？

`stow` 背后主要的概念在程序手册中有很好的解释：

>
> Stow 使用的方法是将每个软件包安装到自己的目录树中，然后使用符号链接使它看起来像文件一样安装在公共的目录树中
>
>
>

为了更好地理解这个软件的运作，我们来分析一下它的关键概念：

#### stow 文件目录

stow 目录是包含所有 stow 软件包的根目录，每个包都有自己的子目录。典型的 stow 目录是 `/usr/local/stow`：在其中，每个子目录代表一个软件包。

#### stow 软件包

如上所述，stow 目录包含多个“软件包”，每个软件包都位于自己单独的子目录中，通常以程序本身命名。包就是与特定软件相关的文件和目录列表，作为一个实体进行管理。

#### stow 目标目录

stow 目标目录解释起来是一个非常简单的概念。它是包文件应该安装到的目录。默认情况下，stow 目标目录被视作是调用 stow 的目录。这种行为可以通过使用 `-t` 选项（ `--target` 的简写）轻松改变，这使我们可以指定一个替代目录。

### 一个实际的例子

我相信一个好的例子胜过 1000 句话，所以让我来展示 `stow` 如何工作。假设我们想编译并安装 `libx264`，首先我们克隆包含其源代码的仓库：

```
$ git clone git://git.videolan.org/x264.git

```

运行该命令几秒钟后，将创建 `x264` 目录，它将包含准备编译的源代码。我们切换到 `x264` 目录中并运行 `configure` 脚本，将 `--prefix` 指定为 `/usr/local/stow/libx264` 目录。

```
$ cd x264 && ./configure --prefix=/usr/local/stow/libx264

```

然后我们构建该程序并安装它：

```
$ make
# make install

```

`x264` 目录应该创建在 `stow` 目录内：它包含了所有通常直接安装在系统中的东西。 现在，我们所要做的就是调用 `stow`。 我们必须从 `stow` 目录内运行这个命令，通过使用 `-d` 选项来手动指定 `stow` 目录的路径（默认为当前目录），或者通过如前所述用 `-t` 指定目标。我们还应该提供要作为参数存储的软件包的名称。 在这里，我们从 `stow` 目录运行程序，所以我们需要输入的内容是：

```
# stow libx264

```

libx264 软件包中包含的所有文件和目录现在已经在调用 stow 的父目录 (/usr/local) 中进行了符号链接，因此，例如在 `/usr/local/ stow/x264/bin` 中包含的 libx264 二进制文件现在符号链接在 `/usr/local/bin` 之中，`/usr/local/stow/x264/etc` 中的文件现在符号链接在 `/usr/local/etc` 之中等等。通过这种方式，系统将显示文件已正常安装，并且我们可以容易地跟踪我们编译和安装的每个程序。要反转该操作，我们只需使用 `-D` 选项：

```
# stow -d libx264

```

完成了！符号链接不再存在：我们只是“卸载”了一个 stow 包，使我们的系统保持在一个干净且一致的状态。 在这一点上，我们应该清楚为什么 stow 还可以用于管理点文件。 通常的做法是在 git 仓库中包含用户特定的所有配置文件，以便轻松管理它们并使它们在任何地方都可用，然后使用 stow 将它们放在适当位置，如放在用户主目录中。

stow 还会阻止你错误地覆盖文件：如果目标文件已经存在，并且没有指向 stow 目录中的包时，它将拒绝创建符号链接。 这种情况在 stow 术语中称为冲突。

就是这样！有关选项的完整列表，请参阅 stow 帮助页，并且不要忘记在评论中告诉我们你对此的看法。

---

via: <https://linuxconfig.org/how-to-use-gnu-stow-to-manage-programs-installed-from-source-and-dotfiles>

作者：[Egidio Docile](https://linuxconfig.org) 译者：[MjSeven](https://github.com/MjSeven) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


什么是容器？为什么我们关注它？

Summary: 什么是容器？你需要它们吗？为什么？在这篇文章中，我们会回答这些基本问题。

什么是容器？你需要它们吗？为什么？在这篇文章中，我们会回答这些基本问题。

# 什么是容器？为什么我们关注它？

<img src="content_image/album_201803_22_083753hzcx8kxvux8d7ckg.jpg" alt="" title="">

什么是容器？你需要它们吗？为什么？在这篇文章中，我们会回答这些基本问题。

但是，为了回答这些问题，我们要提出更多的问题。当你开始考虑怎么用容器适配你的工作时，你需要弄清楚：你在哪开发应用？你在哪测试它？你在哪使用它？

你可能在你的笔记本电脑上开发应用，你的电脑上已经装好了所需要的库文件、扩展包、开发工具和开发框架。它在一个模拟生产环境的机器上进行测试，然后被用于生产环境。问题是这三种环境不一定都是一样的；它们没有同样的工具、框架和库。你在你机器上开发的应用不一定可以在生产环境中正常工作。

容器解决了这个问题。正如 Docker 解释的，“容器镜像是软件的一个轻量的、独立的、可执行的包，包括了执行它所需要的所有东西：代码、运行环境、系统工具、系统库、设置。”

这代表着，一旦一个应用被封装成容器，那么它所依赖的下层环境就不再重要了。它可以在任何地方运行，甚至在混合云环境下也可以。这是容器在开发人员，执行团队，甚至 CIO （信息主管）中变得如此流行的原因之一。

### 容器对开发人员的好处

现在开发人员或运维人员不再需要关注他们要使用什么平台来运行应用。开发人员不会再说：“这在我的系统上运行得好好的。”

容器的另一个重大优势是它的隔离性和安全性。因为容器将应用和运行平台隔离开了，应用以及它周边的东西都会变得安全。同时，不同的团队可以在一台设备上同时运行不同的应用——对于传统应用来说这是不可以的。

这不是虚拟机（ VM ）所提供的吗？既是，也不是。虚拟机可以隔离应用，但它负载太高了。[在一份文献中](https://www.ubuntu.com/containers)，Canonical 比较了容器和虚拟机，结果是：“容器提供了一种新的虚拟化方法，它有着和传统虚拟机几乎相同的资源隔离水平。但容器的负载更小，它占用更少的内存，更为高效。这意味着可以实现高密度的虚拟化：一旦安装，你可以在相同的硬件上运行更多应用。”另外，虚拟机启动前需要更多的准备，而容器只需几秒就能运行，可以瞬间启动。

### 容器对应用生态的好处

现在，一个庞大的，由供应商和解决方案组成的生态系统已经可以让公司大规模地运用容器，不管是用于编排、监控、记录或者生命周期管理。

为了保证容器可以运行在任何地方，容器生态系统一起成立了[开源容器倡议](https://www.opencontainers.org/)（OCI）。这是一个 Linux 基金会的项目，目标在于创建关于容器运行环境和容器镜像格式这两个容器核心部分的规范。这两个规范确保容器领域中不会有任何不一致。

在很长的一段时间里，容器是专门用于 Linux 内核的，但微软和 Docker 的密切合作将容器带到了微软平台上。现在你可以在 Linux、Windows、Azure、AWS、Google 计算引擎、Rackspace，以及大型计算机上使用容器。甚至 VMware 也正在发展容器，它的 [vSphere Integrated Container](https://www.vmware.com/products/vsphere/integrated-containers.html)（VIC）允许 IT 专业人员在他们平台的传统工作负载上运行容器。

### 容器对 CIO 的好处

容器在开发人员中因为以上的原因而变得十分流行，同时他们也给 CIO 提供了很大的便利。将工作负载迁移到容器中的优势正在改变着公司运行的模式。

传统的应用有大约十年的生命周期。新版本的发布需要多年的努力，因为应用是依赖于平台的，有时几年也不能到达产品阶段。由于这个生命周期，开发人员会尽可能在应用里塞满各种功能，这会使应用变得庞大笨拙，漏洞百出。

这个过程影响了公司内部的创新文化。当人们几个月甚至几年都不能看到他们的创意被实现时，他们就不再有动力了。

容器解决了这个问题。因为你可以将应用切分成更小的微服务。你可以在几周或几天内开发、测试和部署。新特性可以添加成为新的容器。他们可以在测试结束后以最快的速度被投入生产。公司可以更快转型，超过他们的竞争者。因为想法可以被很快转化为容器并部署，这个方式使得创意爆炸式增长。

### 结论

容器解决了许多传统工作负载所面对的问题。但是，它并不能解决所有 IT 专业人员面对的问题。它只是众多解决方案中的一个。在下一篇文章中，我们将会覆盖一些容器的基本术语，然后我们会解释如何开始构建容器。

通过 Linux 基金会和 edX 提供的免费的 [“Introduction to Linux”](https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux) 课程学习更多 Linux 知识。

---

via: <https://www.linux.com/blog/intro-to-Linux/2017/12/what-are-containers-and-why-should-you-care>

作者：[wapnil Bhartiya](https://www.linux.com/users/arnieswap) 译者：[lonaparte](https://github.com/lonaparte) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


用 Python 构建你自己的 RSS 提示系统

# 用 Python 构建你自己的 RSS 提示系统

<img src="content_image/album_201803_22_085200jaz81hchunkkch0g.jpg" alt="" title="">

人生苦短，我用 Python，Python 是非常棒的快速构建应用程序的编程语言。在这篇文章中我们将学习如何使用 Python 去构建一个 RSS 提示系统，目标是使用 Fedora 快乐地学习 Python。如果你正在寻找一个完整的 RSS 提示应用程序，在 Fedora 中已经准备好了几个包。

### Fedora 和 Python —— 入门知识

Python 3.6 在 Fedora 中是默认安装的，它包含了 Python 的很多标准库。标准库提供了一些可以让我们的任务更加简单完成的模块的集合。例如，在我们的案例中，我们将使用 [sqlite3](https://docs.python.org/3/library/sqlite3.html) 模块在数据库中去创建表、添加和读取数据。在这个案例中，我们试图去解决的是这样的一个特定问题，在标准库中没有包含，而有可能已经有人为我们开发了这样一个模块。最好是使用像大家熟知的 [PyPI](https://pypi.python.org/pypi) Python 包索引去搜索一下。在我们的示例中，我们将使用 [feedparser](https://pypi.python.org/pypi/feedparser/5.2.1) 去解析 RSS 源。

因为 feedparser 并不是标准库，我们需要将它安装到我们的系统上。幸运的是，在 Fedora 中有这个 RPM 包，因此，我们可以运行如下的命令去安装 feedparser：

```
$ sudo dnf install python3-feedparser

```

我们现在已经拥有了编写我们的应用程序所需的东西了。

### 存储源数据

我们需要存储已经发布的文章的数据，这样我们的系统就可以只提示新发布的文章。我们要保存的数据将是用来辨别一篇文章的唯一方法。因此，我们将存储文章的标题和发布日期。

因此，我们来使用 Python sqlite3 模块和一个简单的 SQL 语句来创建我们的数据库。同时也添加一些后面将要用到的模块（feedparse，smtplib，和 email）。

#### 创建数据库

```
#!/usr/bin/python3
import sqlite3
import smtplib
from email.mime.text import MIMEText

import feedparser

db_connection = sqlite3.connect('/var/tmp/magazine_rss.sqlite')
db = db_connection.cursor()
db.execute(' CREATE TABLE IF NOT EXISTS magazine (title TEXT, date TEXT)')

```

这几行代码创建一个名为 `magazine_rss.sqlite` 文件的新 sqlite 数据库，然后在数据库创建一个名为 `magazine` 的新表。这个表有两个列 —— `title` 和 `date` —— 它们能存诸 TEXT 类型的数据，也就是说每个列的值都是文本字符。

#### 检查数据库中的旧文章

由于我们仅希望增加新的文章到我们的数据库中，因此我们需要一个功能去检查 RSS 源中的文章在数据库中是否存在。我们将根据它来判断是否发送（有新文章的）邮件提示。Ok，现在我们来写这个功能的代码。

```
def article_is_not_db(article_title, article_date):
    """ Check if a given pair of article title and date
    is in the database.
    Args:
        article_title (str): The title of an article
        article_date  (str): The publication date of an article
    Return:
        True if the article is not in the database
        False if the article is already present in the database
    """
    db.execute("SELECT * from magazine WHERE title=? AND date=?", (article_title, article_date))
    if not db.fetchall():
        return True
    else:
        return False

```

这个功能的主要部分是一个 SQL 查询，我们运行它去搜索数据库。我们使用一个 `SELECT` 命令去定义我们将要在哪个列上运行这个查询。我们使用 `*` 符号去选取所有列（`title` 和 `date`）。然后，我们使用查询的 `WHERE` 条件 `article_title` 和 `article_date` 去匹配标题和日期列中的值，以检索出我们需要的内容。

最后，我们使用一个简单的返回 `True` 或者 `False` 的逻辑来表示是否在数据库中找到匹配的文章。

#### 在数据库中添加新文章

现在我们可以写一些代码去添加新文章到数据库中。

```
def add_article_to_db(article_title, article_date):
    """ Add a new article title and date to the database
    Args:
        article_title (str): The title of an article
        article_date (str): The publication date of an article
    """
    db.execute("INSERT INTO magazine VALUES (?,?)", (article_title, article_date))
    db_connection.commit()

```

这个功能很简单，我们使用了一个 SQL 查询去插入一个新行到 `magazine` 表的 `article_title` 和 `article_date` 列中。然后提交它到数据库中永久保存。

这些就是在数据库中所需要的东西，接下来我们看一下，如何使用 Python 实现提示系统和发送电子邮件。

### 发送电子邮件提示

我们使用 Python 标准库模块 smtplib 来创建一个发送电子邮件的功能。我们也可以使用标准库中的 email 模块去格式化我们的电子邮件信息。

```
def send_notification(article_title, article_url):
    """ Add a new article title and date to the database

    Args:
        article_title (str): The title of an article
        article_url (str): The url to access the article
    """

    smtp_server = smtplib.SMTP('smtp.gmail.com', 587)
    smtp_server.ehlo()
    smtp_server.starttls()
    smtp_server.login('your_email@gmail.com', '123your_password')
    msg = MIMEText(f'\nHi there is a new Fedora Magazine article : {article_title}. \nYou can read it here {article_url}')
    msg['Subject'] = 'New Fedora Magazine Article Available'
    msg['From'] = 'your_email@gmail.com'
    msg['To'] = 'destination_email@gmail.com'
    smtp_server.send_message(msg)
    smtp_server.quit()

```

在这个示例中，我使用了谷歌邮件系统的 smtp 服务器去发送电子邮件，在你自己的代码中你需要将它更改为你自己的电子邮件服务提供者的 SMTP 服务器。这个功能是个样板，大多数的内容要根据你的 smtp 服务器的参数来配置。代码中的电子邮件地址和凭证也要更改为你自己的。

如果在你的 Gmail 帐户中使用了双因子认证，那么你需要配置一个密码应用程序为你的这个应用程序提供一个唯一密码。可以看这个 [帮助页面](https://support.google.com/accounts/answer/185833?hl=en)。

### 读取 Fedora Magazine 的 RSS 源

我们已经有了在数据库中存储文章和发送提示电子邮件的功能，现在来创建一个解析 Fedora Magazine RSS 源并提取文章数据的功能。

```
def read_article_feed():
    """ Get articles from RSS feed """
    feed = feedparser.parse('https://fedoramagazine.org/feed/')
    for article in feed['entries']:
        if article_is_not_db(article['title'], article['published']):
            send_notification(article['title'], article['link'])
            add_article_to_db(article['title'], article['published'])

if __name__ == '__main__':
    read_article_feed()
    db_connection.close()

```

在这里我们将使用 `feedparser.parse` 功能。这个功能返回一个用字典表示的 RSS 源，对于 feedparser 的完整描述可以参考它的 [文档](https://pythonhosted.org/feedparser/reference.html)。

RSS 源解析将返回最后的 10 篇文章作为 `entries`，然后我们提取以下信息：标题、链接、文章发布日期。因此，我们现在可以使用前面定义的检查文章是否在数据库中存在的功能，然后，发送提示电子邮件并将这个文章添加到数据库中。

当运行我们的脚本时，最后的 `if` 语句运行我们的 `read_article_feed` 功能，然后关闭数据库连接。

### 运行我们的脚本

给脚本文件赋于正确运行权限。接下来，我们使用 cron 实用程序去每小时自动运行一次我们的脚本。cron 是一个作业计划程序，我们可以使用它在一个固定的时间去运行一个任务。

```
$ chmod a+x my_rss_notifier.py
$ sudo cp my_rss_notifier.py /etc/cron.hourly

```

为了使该教程保持简单，我们使用了 `cron.hourly` 目录每小时运行一次我们的脚本，如果你想学习关于 cron 的更多知识以及如何配置 crontab，请阅读 cron 的 wikipedia [页面](https://en.wikipedia.org/wiki/Cron)。

### 总结

在本教程中，我们学习了如何使用 Python 去创建一个简单的 sqlite 数据库、解析一个 RSS 源、以及发送电子邮件。我希望通过这篇文章能够向你展示，使用 Python 和 Fedora 构建你自己的应用程序是件多么容易的事。

这个脚本在 [GitHub](https://github.com/cverna/rss_feed_notifier) 上可以找到。

---

via: <https://fedoramagazine.org/never-miss-magazines-article-build-rss-notification-system/>

作者：[Clément Verna](https://fedoramagazine.org) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Summary: Meltdown 和 Specter 漏洞的最恐怖的现实之一是它们涉及非常广泛。几乎每台现代计算机都会受到一些影响。真正的问题是你是否受到了影响？每个系统都处于不同的脆弱状态，具体取决于已经或者还没有打补丁的软件。

# 如何检查你的 Linux 系统是否存在 Meltdown 或者 Spectre 漏洞

Meltdown 和 Specter 漏洞的最恐怖的现实之一是它们涉及非常广泛。几乎每台现代计算机都会受到一些影响。真正的问题是*你*是否受到了影响？每个系统都处于不同的脆弱状态，具体取决于已经或者还没有打补丁的软件。

由于 Meltdown 和 Spectre 都是相当新的漏洞，并且事情正在迅速发展，所以告诉你需要注意什么或在系统上修复了什么并非易事。有一些工具可以提供帮助。它们并不完美，但它们可以帮助你找出你需要知道的东西。

### 简单测试

顶级的 Linux 内核开发人员之一提供了一种简单的方式来检查系统在 Meltdown 和 Specter 漏洞方面的状态。它是简单的，也是最简洁的，但它不适用于每个系统。有些发行版不支持它。即使如此，也值得一试。

```
grep . /sys/devices/system/cpu/vulnerabilities/*

```

你应该看到与上面截图类似的输出。很有可能你会发现系统中至少有一个漏洞还存在。这的确是真的，因为 Linux 在减轻 Specter v1 影响方面还没有取得任何进展。

### 脚本

如果上面的方法不适合你，或者你希望看到更详细的系统报告，一位开发人员已创建了一个 shell 脚本，它将检查你的系统来查看系统收到什么漏洞影响，还有做了什么来减轻 Meltdown 和 Spectre 的影响。

要得到脚本，请确保你的系统上安装了 Git，然后将脚本仓库克隆到一个你不介意运行它的目录中。

```
cd ~/Downloads
git clone https://github.com/speed47/spectre-meltdown-checker.git

```

这不是一个大型仓库，所以它应该只需要几秒钟就克隆完成。完成后，输入新创建的目录并运行提供的脚本。

```
cd spectre-meltdown-checker
./spectre-meltdown-checker.sh

```

你会在终端看到很多输出。别担心，它不是太难理解。首先，脚本检查你的硬件，然后运行三个漏洞检查：Specter v1、Spectre v2 和 Meltdown。每个漏洞都有自己的部分。在这之间，脚本明确地告诉你是否受到这三个漏洞的影响。

每个部分为你提供了潜在的可用的缓解方案，以及它们是否已被应用。这里需要你的一点常识。它给出的决定可能看起来有冲突。研究一下，看看它所说的修复是否实际上完全缓解了这个问题。

### 这意味着什么

所以，要点是什么？大多数 Linux 系统已经针对 Meltdown 进行了修补。如果你还没有更新，你应该更新一下。 Specter v1 仍然是一个大问题，到目前为止还没有取得很大进展。Spectre v2 将取决于你的发行版以及它选择应用的补丁。无论哪种工具都说，没有什么是完美的。做好研究并留意直接来自内核和发行版开发者的信息。

---

via: <https://www.maketecheasier.com/check-linux-meltdown-spectre-vulnerability/>

作者：[Nick Congleton](https://www.maketecheasier.com/author/nickcongleton/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Python Plumbum 简介：用 Python 来写脚本

Summary: 你是否曾希望将 shell 脚本紧凑地融入到真正的编程语言里面？ 那么可以了解下 Plumbum Shell 组合器。

# Python Plumbum 简介：用 Python 来写脚本

<img src="content_image/album_201803_22_101111fawijaevfv3d7e3l.jpg" alt="" title="">

### Plumbum：Shell 组合器

你是否曾希望将 shell 脚本紧凑地融入到**真正**的编程语言里面？ 那么可以了解下 Plumbum Shell 组合器。Plumbum （lead 的拉丁语，以前用来制作管道）是一个小型但功能丰富的类库，用于以 Python 进行类似 shell 脚本编程。该库的理念是 “**永远不要再写 shell 脚本**”，因此它试图合理地模仿 shell 语法（shell 组合器），同时保持 **Python 特性和跨平台**。

除了[类似 shell 的语法](https://plumbum.readthedocs.io/en/latest/local_commands.html#guide-local-commands)和[便捷的快捷方式](https://plumbum.readthedocs.io/en/latest/utils.html#guide-utils)之外，该库还提供本地和[远程](https://plumbum.readthedocs.io/en/latest/remote.html#guide-remote-commands)命令执行（通过 SSH）、本地和远程文件系统[路径](https://plumbum.readthedocs.io/en/latest/paths.html#guide-paths)、简单的工作目录和环境[操作](https://plumbum.readthedocs.io/en/latest/local_machine.html#guide-local-machine)、快捷访问 ANSI 颜色，以及[编程命令行接口（CLI）](https://plumbum.readthedocs.io/en/latest/cli.html#guide-cli)应用程序工具包。现在让我们看一些代码！

其最新版本 1.6.6 发布于 2018 年 2 月 12 日。

### 快捷使用指南

####

#### 基本使用

```
>>> from plumbum import local
>>> ls = local["ls"]
>>> ls
LocalCommand(<LocalPath /bin/ls>)
>>> ls()
u'build.py\ndist\ndocs\nLICENSE\nplumbum\nREADME.rst\nsetup.py\ntests\ntodo.txt\n'
>>> notepad = local["c:\\windows\\notepad.exe"]
>>> notepad()                                   # Notepad window pops up
u''                                             # Notepad window is closed by user, command returns

```

不需要为每个你想使用的命令写 `xxx = local["xxx"]`，你可以[导入命令行](https://plumbum.readthedocs.io/en/latest/local_commands.html#import-hack)：

```
>>> from plumbum.cmd import grep, wc, cat, head
>>> grep
LocalCommand(<LocalPath /bin/grep>)

```

参见[本地命令行](https://plumbum.readthedocs.io/en/latest/local_commands.html#guide-local-commands) 。

#### 管道

```
>>> chain = ls["-a"] | grep["-v", "\\.py"] | wc["-l"]
>>> print chain
/bin/ls -a | /bin/grep -v '\.py' | /usr/bin/wc -l
>>> chain()
u'13\n'

```

参见[管道](https://plumbum.readthedocs.io/en/latest/local_commands.html#guide-local-commands-pipelining)。

#### 重定向

```
>>> ((cat < "setup.py") | head["-n", 4])()
u'#!/usr/bin/env python\nimport os\n\ntry:\n'
>>> (ls["-a"] > "file.list")()
u''
>>> (cat["file.list"] | wc["-l"])()
u'17\n'

```

参见[输入/输出重定向](https://plumbum.readthedocs.io/en/latest/local_commands.html#guide-local-commands-redir)。

#### 工作目录操作

```
>>> local.cwd
<Workdir /home/tomer/workspace/plumbum>
>>> with local.cwd(local.cwd / "docs"):
...     chain()
...
u'15\n'

```

参见[路径](https://plumbum.readthedocs.io/en/latest/paths.html#guide-paths)和[本地对象](https://plumbum.readthedocs.io/en/latest/local_machine.html#guide-local-machine) 。

#### 前台后和后台执行

```
>>> from plumbum import FG, BG
>>> (ls["-a"] | grep["\\.py"]) & FG         # The output is printed to stdout directly
build.py
.pydevproject
setup.py
>>> (ls["-a"] | grep["\\.py"]) & BG         # The process runs "in the background"
<Future ['/bin/grep', '\\.py'] (running)>

```

参见[前台和后台](https://plumbum.readthedocs.io/en/latest/local_commands.html#guide-local-commands-bgfg)。

#### 命令行嵌套

```
>>> from plumbum.cmd import sudo
>>> print sudo[ifconfig["-a"]]
/usr/bin/sudo /sbin/ifconfig -a
>>> (sudo[ifconfig["-a"]] | grep["-i", "loop"]) & FG
lo        Link encap:Local Loopback
          UP LOOPBACK RUNNING  MTU:16436  Metric:1

```

参见[命令行嵌套](https://plumbum.readthedocs.io/en/latest/local_commands.html#guide-local-commands-nesting)。

#### 远程命令（通过 SSH）

```
>>> from plumbum import SshMachine
>>> remote = SshMachine("somehost", user = "john", keyfile = "/path/to/idrsa")
>>> r_ls = remote["ls"]
>>> with remote.cwd("/lib"):
...     (r_ls | grep["0.so.0"])()
...
u'libusb-1.0.so.0\nlibusb-1.0.so.0.0.0\n'

```

参见[远程](https://plumbum.readthedocs.io/en/latest/remote.html#guide-remote)。

#### CLI 应用程序

```
import logging
from plumbum import cli

class MyCompiler(cli.Application):
    verbose = cli.Flag(["-v", "--verbose"], help = "Enable verbose mode")
    include_dirs = cli.SwitchAttr("-I", list = True, help = "Specify include directories")

    @cli.switch("-loglevel", int)
    def set_log_level(self, level):
        """Sets the log-level of the logger"""
        logging.root.setLevel(level)

    def main(self, *srcfiles):
        print "Verbose:", self.verbose
        print "Include dirs:", self.include_dirs
        print "Compiling:", srcfiles

if __name__ == "__main__":
    MyCompiler.run()

```

输出样例：

```
$ python simple_cli.py -v -I foo/bar -Ispam/eggs x.cpp y.cpp z.cpp
Verbose: True
Include dirs: ['foo/bar', 'spam/eggs']
Compiling: ('x.cpp', 'y.cpp', 'z.cpp')

```

参见[命令行应用程序](https://plumbum.readthedocs.io/en/latest/cli.html#guide-cli)。

#### 颜色和风格

```
from plumbum import colors
with colors.red:
    print("This library provides safe, flexible color access.")
    print(colors.bold | "(and styles in general)", "are easy!")
print("The simple 16 colors or",
      colors.orchid & colors.underline | '256 named colors,',
      colors.rgb(18, 146, 64) | "or full rgb colors" ,
      'can be used.')
print("Unsafe " + colors.bg.dark_khaki + "color access" + colors.bg.reset + " is available too.")

```

输出样例：

```
This library provides safe color access.
Color (and styles in general) are easy!
The simple 16 colors, 256 named colors, or full hex colors can be used.
Unsafe color access is available too.

```

参见[颜色](https://plumbum.readthedocs.io/en/latest/colors.html#guide-colors)。

### 开发和安装

该库在 [Github](https://github.com/tomerfiliba/plumbum) 上开发，非常乐意接受来自用户的[补丁](https://help.github.com/send-pull-requests/)。请使用 GitHub 的内置 [issue 跟踪器](https://github.com/tomerfiliba/plumbum/issues)报告您遇到的任何问题或提出功能上的需求。该库在 [IMIT 许可](https://github.com/tomerfiliba/plumbum/blob/master/LICENSE)下发布。

#### 要求

Plumbum 支持 Python 2.6-3.6 和 PyPy，并且通过 [Travis CI](https://travis-ci.org/tomerfiliba/plumbum) 和 [Appveyor](https://ci.appveyor.com/project/HenrySchreiner/plumbum/branch/master) 持续地在 Linux，Mac 和 Windows 机器上测试。Plumbum 在任何类 Unix 的机器都应该可以正常工作，但是在 Windows 上，你也许需要安装一个合适的 [coreutils](https://www.wikiwand.com/en/Coreutils) 环境并把其加入到你的`PATH`环境变量中。我推荐 [mingw](http://mingw.org/)（与 [Windows Git](http://msysgit.github.io/) 捆绑在一起），但是 [cygwin](http://www.cygwin.com/) 应该也可以。如果你仅仅是使用 Plumbum 代替 Popen 来运行 Windows 程序，那么就不需要 Unix 工具了。 注意远程命令的执行，你需要一个 openSHH 兼容的客户端（同样与 Windows Git 捆绑在一起）和一个 bash 兼容的 shell，也需要在主机上有一个 coreutils 环境。

#### 下载

你可以在 [**Python Package Index**](https://pypi.python.org/pypi/plumbum#downloads) （多种格式）下载该库，或者直接运行 `pip install plumbum`。如果你使用 Anaconda，你可以使用 `conda install -c conda-forge plumbum` 从 `conda-forge` 通道获取。

### 用户指南

用户指南涵盖了 Plumbum 大部分功能，拥有大量的代码片段，你可以不用花多少时间即可开始使用。该指南逐渐介绍概念和"语法"，因此推荐你按照顺序阅读。一个[**有效的快速参考指南**](https://plumbum.readthedocs.io/en/latest/quickref.html#guide-quickref)。 *略。。。*

####

### 关于

Plumburn 最初的目的是让本地和远程程序轻松地执行，假设没有比老的 ssh 更时髦的东西了。在此基础上，设计了一个文件系统抽象层，以便能够无缝地处理本地和远程文件。 我有这个想法一段时间了，直到我必须要个给我当前工作的项目写一个构建脚本，我决定使用 shell 脚本，现在是实现它的时候了。Plumbum 诞生自 `Path` 类的片段和我为 [**RPyC**](http://rpyc.readthedocs.io/en/latest/) 写的 `SshContext` 和 `SshTunnel` 类。`Path` 类是我为前面说的构建系统写的。当我将两者与 *shell 组合器*（因为 shell 脚本在这里确实有优势）组合在一起时，奇迹就发生了，便产生了Plumbun。

### 致谢

该项目受到了 [**Andrew Moffat**](https://github.com/amoffat) 的 **PBS**（现在被称作 [**sh**](http://amoffat.github.io/sh/)）启发，并且借用了他的一些思想（即像函数一样看待程序，导入命令行的技巧）。然而我感觉在 PBS 中有太多的神秘的东西，当我编写类 shell 程序时，语法不是我想要的。关于这个问题我联系了 Andrew，但是他想让 PBS 保持这种状态。除此之外，两个库走不同的方向，Plumbum 试图提供一种更合理的方法。

Plumbum 也向 [**Rotem Yaari**](https://github.com/vmalloc/) 致敬，他为特定的目的建议了一个代号为 `pyplatform` 的库，但是尚未实现过。


Red 语言建立基金会，发力区块链

Summary: 基金会的职能如在其宣告和 RED 白皮书中所说，是管理整个 Red 开源项目，并使用 RED 通证来建立一个新的开源项目经济模式。

# Red 语言建立基金会，发力区块链

Red 语言在其官网宣布，其于 2018 年 1 月在法国巴黎建立了基金会。Red 基金会托管在 [法国高等研究实践学院（EPHE）](https://www.ephe.fr/en) ，由 [François Jouen](https://www.ephe.fr/ecole/nos-enseignants-chercheurs/francois-jouen) 所领导的“人与人工认知研究”部门所管理，[François Jouen](https://www.ephe.fr/ecole/nos-enseignants-chercheurs/francois-jouen) 是 Red 语言中著名的图像处理框架 [RedCV](https://github.com/ldci/redCV) 的作者。

<img src="content_image/album_201803_23_143716z6tjtnm4kmmgkww1.jpg" alt="" title="">

基金会的职能如在其[宣告](http://www.red-lang.org/2017/12/leaping-into-future-red-goes-blockchain.html)和 [RED 白皮书](https://ico.red-lang.org/RED-whitepaper.pdf)中所说，是管理整个 Red 开源项目，并使用 RED 通证来建立一个新的开源项目经济模式。为达成此目标，位于 GitHub 上的 Red 代码库中的所有版权拥有者都被要求将其权力让渡到基金会。而 Nenad 作为其源代码中最大的版权拥有者，将率先让渡（即修改源代码中的文件头和许可证文件）。

据 Red 基金会去年底[发布的消息](http://www.red-lang.org/2017/12/leaping-into-future-red-goes-blockchain.html)，Red 语言将发起多个支持区块链的子项目，包括用于智能合约编程的 Red/CCC，可以直接编译成支持以太坊虚拟机的字节码，也将会支持其它链，如 NEO；更小的运行时环境（大约 1mb，压缩后约 300kb）的 Red DApp，而采用 [Electron](https://en.wikipedia.org/wiki/Electron_(software_framework)) 框架的 DApp 需要 50 ~ 150 Mb。

Red 基金会由以下几个部门组成：

* 管理团队
	+ Nenad Rakocevic，总裁
	+ Francois Jouen，副总裁
	+ Azouz Guizani，财务主管
* 由 [Gregg Irwin](https://github.com/greggirwin) 领导的运营团队。[Peter W A Wood](https://github.com/peterwawood) 是首位成员，将来还会有更多正式成员。
* 由荣誉会员组成的顾问团队。

运营团队当前正在进行如下工作：

* 基金会网站，功能包括：
	+ 定期发布报告的博客平台。
	+ 关于 RED 通证的全部信息（使用情况、奖励规则和金额）。
	+ 悬赏的贡献任务（支付 RED 通证）。
* 制定为之前的贡献者的既往贡献发放 RED 通证的规则（从 2011 年 Red 的 GitHub 仓库建立开始算起）。当规则和要奖励的通证数量确定之后会尽快发放。这需要收集贡献及贡献者的列表。
* 确定运营团队的决策流程。
* 确定基金会的成员资格规则。
* 负责重新设计 red-lang.org 网站，并将其移动到新平台。

出于信息传递和透明度的考虑，所有这些任务及结果都将发布到基金会的网站上。

此外，Red 基金会也在寻求合作伙伴，以实现其简化人类编程的愿景，特别是在区块链领域。目前大部分这些工作都由其合作伙伴如 [NEO 委员会](https://neo.org/)、 [Enuma](https://www.enuma.io/index.html)（一家领先的香港区块链服务公司）来完成。


Tlog：录制/播放终端 IO 和会话的工具

# Tlog：录制/播放终端 IO 和会话的工具

Tlog 是 Linux 中终端 I/O 录制和回放软件包。它用于实现一个集中式用户会话录制。它将所有经过的消息录制为 JSON 消息。录制为 JSON 格式的主要目的是将数据传送到 ElasticSearch 之类的存储服务，可以从中搜索和查询，以及回放。同时，它们保留所有通过的数据和时序。

Tlog 包含三个工具，分别是 `tlog-rec`、tlog-rec-session`和`tlog-play`。

* `tlog-rec` 工具一般用于录制终端、程序或 shell 的输入或输出。
* `tlog-rec-session` 工具用于录制整个终端会话的 I/O，包括录制的用户。
* `tlog-play` 工具用于回放录制。

在本文中，我将解释如何在 CentOS 7.4 服务器上安装 Tlog。

### 安装

在安装之前，我们需要确保我们的系统满足编译和安装程序的所有软件要求。在第一步中，使用以下命令更新系统仓库和软件包。

```
# yum update

```

我们需要安装此软件安装所需的依赖项。在安装之前，我已经使用这些命令安装了所有依赖包。

```
# yum install wget gcc
# yum install systemd-devel json-c-devel libcurl-devel m4

```

完成这些安装后，我们可以下载该工具的[源码包](https://github.com/Scribery/tlog/releases/download/v3/tlog-3.tar.gz)并根据需要将其解压到服务器上：

```
# wget https://github.com/Scribery/tlog/releases/download/v3/tlog-3.tar.gz
# tar -xvf tlog-3.tar.gz
# cd tlog-3

```

现在，你可以使用我们通常的配置和编译方法开始构建此工具。

```
# ./configure --prefix=/usr --sysconfdir=/etc && make
# make install
# ldconfig

```

最后，你需要运行 `ldconfig`。它对命令行中指定目录、`/etc/ld.so.conf` 文件，以及信任的目录（ `/lib` 和 `/usr/lib`）中最近的共享库创建必要的链接和缓存。

### Tlog 工作流程图

首先，用户通过 PAM 进行身份验证登录。名称服务交换器（NSS）提供的 `tlog` 信息是用户的 shell。这初始化了 tlog 部分，并从环境变量/配置文件收集关于实际 shell 的信息，并在 PTY 中启动实际的 shell。然后通过 syslog 或 sd-journal 开始录制在终端和 PTY 之间传递的所有内容。

### 用法

你可以使用 `tlog-rec` 录制一个会话并使用 `tlog-play` 回放它，以测试新安装的 tlog 是否能够正常录制和回放会话。

#### 录制到文件中

要将会话录制到文件中，请在命令行中执行 `tlog-rec`，如下所示：

```
tlog-rec --writer=file --file-path=tlog.log

```

该命令会将我们的终端会话录制到名为 `tlog.log` 的文件中，并将其保存在命令中指定的路径中。

#### 从文件中回放

你可以在录制过程中或录制后使用 `tlog-play` 命令回放录制的会话。

```
tlog-play --reader=file --file-path=tlog.log

```

该命令从指定的路径读取先前录制的文件 `tlog.log`。

### 总结

Tlog 是一个开源软件包，可用于实现集中式用户会话录制。它主要是作为一个更大的用户会话录制解决方案的一部分使用，但它被设计为独立且可重用的。该工具可以帮助录制用户所做的一切，并将其存储在服务器的某个位置，以备将来参考。你可以从这个[文档](https://github.com/Scribery/tlog/blob/master/README.md)中获得关于这个软件包使用的更多细节。我希望这篇文章对你有用。请发表你的宝贵建议和意见。

**关于 Saheetha Shameer （作者）**

我正在担任高级系统管理员。我是一名快速学习者，有轻微的倾向跟随行业中目前和正在出现的趋势。我的爱好包括听音乐、玩策略游戏、阅读和园艺。我对尝试各种美食也有很高的热情 :-)

---

via: <https://linoxide.com/linux-how-to/tlog-tool-record-play-terminal-io-sessions/>

作者：[Saheetha Shameer](https://linoxide.com/author/saheethas/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


如何在 Linux 上运行你自己的公共时间服务器

# 如何在 Linux 上运行你自己的公共时间服务器

<img src="content_image/album_201803_24_113933blq6i8bblqgll8b2.jpg" alt="" title="">

最重要的公共服务之一就是<ruby> 报时 <rt>  timekeeping </rt></ruby>，但是很多人并没有意识到这一点。大多数公共时间服务器都是由志愿者管理，以满足不断增长的需求。这里学习一下如何运行你自己的时间服务器，为基础公共利益做贡献。（查看 [在 Linux 上使用 NTP 保持精确时间](/article-9462-1.html) 去学习如何设置一台局域网时间服务器）

### 著名的时间服务器滥用事件

就像现实生活中任何一件事情一样，即便是像时间服务器这样的公益项目，也会遭受不称职的或者恶意的滥用。

消费类网络设备的供应商因制造了大混乱而臭名昭著。我回想起的第一件事发生在 2003 年，那时，NetGear 在它们的路由器中硬编码了威斯康星大学的 NTP 时间服务器地址。使得时间服务器的查询请求突然增加，随着 NetGear 卖出越来越多的路由器，这种情况越发严重。更有意思的是，路由器的程序设置是每秒钟发送一次请求，这将使服务器难堪重负。后来 Netgear 发布了升级固件，但是，升级他们的设备的用户很少，并且他们的其中一些用户的设备，到今天为止，还在不停地每秒钟查询一次威斯康星大学的 NTP 服务器。Netgear 给威斯康星大学捐献了一些钱，以帮助弥补他们带来的成本增加，直到这些路由器全部淘汰。类似的事件还有 D-Link、Snapchat、TP-Link 等等。

对 NTP 协议进行反射和放大，已经成为发起 DDoS 攻击的一个选择。当攻击者使用一个伪造的目标受害者的源地址向时间服务器发送请求，称为反射攻击；攻击者发送请求到多个服务器，这些服务器将回复请求，这样就使伪造的源地址受到轰炸。放大攻击是指一个很小的请求收到大量的回复信息。例如，在 Linux 上，`ntpq` 命令是一个查询你的 NTP 服务器并验证它们的系统时间是否正确的很有用的工具。一些回复，比如，对端列表，是非常大的。组合使用反射和放大，攻击者可以将 10 倍甚至更多带宽的数据量发送到被攻击者。

那么，如何保护提供公益服务的公共 NTP 服务器呢？从使用 NTP 4.2.7p26 或者更新的版本开始，它们可以帮助你的 Linux 发行版不会发生前面所说的这种问题，因为它们都是在 2010 年以后发布的。这个发行版都默认禁用了最常见的滥用攻击。目前，[最新版本是 4.2.8p10](http://www.ntp.org/downloads.html)，它发布于 2017 年。

你可以采用的另一个措施是，在你的网络上启用入站和出站过滤器。阻塞宣称来自你的网络的数据包进入你的网络，以及拦截发送到伪造返回地址的出站数据包。入站过滤器可以帮助你，而出站过滤器则帮助你和其他人。阅读 [BCP38.info](http://www.bcp38.info/index.php/Main_Page) 了解更多信息。

### 层级为 0、1、2 的时间服务器

NTP 有超过 30 年的历史了，它是至今还在使用的最老的因特网协议之一。它的用途是保持计算机与世界标准时间（UTC）的同步。NTP 网络是分层组织的，并且同层的设备是对等的。<ruby> 层次 <rt>  Stratum </rt></ruby> 0 包含主报时设备，比如，原子钟。层级 1 的时间服务器与层级 0 的设备同步。层级 2 的设备与层级 1 的设备同步，层级 3 的设备与层级 2 的设备同步。NTP 协议支持 16 个层级，现实中并没有使用那么多的层级。同一个层级的服务器是相互对等的。

过去很长一段时间内，我们都为客户端选择配置单一的 NTP 服务器，而现在更好的做法是使用 [NTP 服务器地址池](http://www.pool.ntp.org/en/use.html)，它使用轮询的 DNS 信息去共享负载。池地址只是为客户端服务的，比如单一的 PC 和你的本地局域网 NTP 服务器。当你运行一台自己的公共服务器时，你不用使用这些池地址。

### 公共 NTP 服务器配置

运行一台公共 NTP 服务器只有两步：设置你的服务器，然后申请加入到 NTP 服务器池。运行一台公共的 NTP 服务器是一种很高尚的行为，但是你得先知道这意味着什么。加入 NTP 服务器池是一种长期责任，因为即使你加入服务器池后，运行了很短的时间马上退出，然后接下来的很多年你仍然会接收到请求。

你需要一个静态的公共 IP 地址，一个至少 512Kb/s 带宽的、可靠的、持久的因特网连接。NTP 使用的是 UDP 的 123 端口。它对机器本身要求并不高，很多管理员在其它的面向公共的服务器（比如，Web 服务器）上顺带架设了 NTP 服务。

配置一台公共的 NTP 服务器与配置一台用于局域网的 NTP 服务器是一样的，只需要几个配置。我们从阅读 [协议规则](http://support.ntp.org/bin/view/Servers/RulesOfEngagement) 开始。遵守规则并注意你的行为；几乎每个时间服务器的维护者都是像你这样的志愿者。然后，从 [StratumTwoTimeServers](http://support.ntp.org/bin/view/Servers/StratumTwoTimeServers?redirectedfrom=Servers.StratumTwo) 中选择 4 到 7 个层级 2 的上游服务器。选择的时候，选取地理位置上靠近（小于 300 英里的）你的因特网服务提供商的上游服务器，阅读他们的访问规则，然后，使用 `ping` 和 `mtr` 去找到延迟和跳数最小的服务器。

以下的 `/etc/ntp.conf` 配置示例文件，包括了 IPv4 和 IPv6，以及基本的安全防护：

```
# stratum 2 server list
server servername_1 iburst
server servername_2 iburst
server servername_3 iburst
server servername_4 iburst
server servername_5 iburst

# access restrictions
restrict -4 default kod noquery nomodify notrap nopeer limited
restrict -6 default kod noquery nomodify notrap nopeer limited

# Allow ntpq and ntpdc queries only from localhost
restrict 127.0.0.1
restrict ::1

```

启动你的 NTP 服务器，让它运行几分钟，然后测试它对远程服务器的查询：

```
$ ntpq -p
 remote refid st t when poll reach delay offset jitter
=================================================================
+tock.no-such-ag 200.98.196.212 2 u 36 64 7 98.654 88.439 65.123
+PBX.cytranet.ne 45.33.84.208 3 u 37 64 7 72.419 113.535 129.313
*eterna.binary.n 199.102.46.70 2 u 39 64 7 92.933 98.475 56.778
+time.mclarkdev. 132.236.56.250 3 u 37 64 5 111.059 88.029 74.919

```

目前表现很好。现在从另一台 PC 上使用你的 NTP 服务器名字进行测试。以下的示例是一个正确的输出。如果有不正确的地方，你将看到一些错误信息。

```
$ ntpdate -q yourservername
server 66.96.99.10, stratum 2, offset 0.017690, delay 0.12794
server 98.191.213.2, stratum 1, offset 0.014798, delay 0.22887
server 173.49.198.27, stratum 2, offset 0.020665, delay 0.15012
server 129.6.15.28, stratum 1, offset -0.018846, delay 0.20966
26 Jan 11:13:54 ntpdate[17293]: adjust time server 98.191.213.2 offset 0.014798 sec

```

一旦你的服务器运行的很好，你就可以向 [manage.ntppool.org](https://manage.ntppool.org/manage) 申请加入池中。

查看官方的手册 [分布式网络时间服务器（NTP）](https://www.eecis.udel.edu/%7Emills/ntp/html/index.html) 学习所有的命令、配置选项、以及高级特性，比如，管理、查询、和验证。访问以下的站点学习关于运行一台时间服务器所需要的一切东西。

通过来自 Linux 基金会和 edX 的免费课程 [“Linux 入门”](https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux) 学习更多 Linux 的知识。

---

via: <https://www.linux.com/learn/intro-to-linux/2018/2/how-run-your-own-public-time-server-linux>

作者：[CARLA SCHRODER](https://www.linux.com/users/cschroder) 译者：[qhwdw](https://github.com/qhwdw) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


解读 ip 命令展示的网络连接信息

Summary: ip 命令可以告诉你很多网络连接配置和状态的信息，但是所有这些词和数字意味着什么？ 让我们深入了解一下，看看所有显示的值都试图告诉你什么。

# 解读 ip 命令展示的网络连接信息

<img src="content_image/album_201803_24_115203by90oee7sbb11y0o.jpg" alt="" title="">

`ip` 命令可以告诉你很多网络连接配置和状态的信息，但是所有这些词和数字意味着什么？ 让我们深入了解一下，看看所有显示的值都试图告诉你什么。

当您使用 `ip a`（或 `ip addr`）命令获取系统上所有网络接口的信息时，您将看到如下所示的内容：

```
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 inet 127.0.0.1/8 scope host lo
 valid_lft forever preferred_lft forever
 inet6 ::1/128 scope host
 valid_lft forever preferred_lft forever
2: enp0s25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
 link/ether 00:1e:4f:c8:43:fc brd ff:ff:ff:ff:ff:ff
 inet 192.168.0.24/24 brd 192.168.0.255 scope global dynamic enp0s25
 valid_lft 57295sec preferred_lft 57295sec
 inet6 fe80::2c8e:1de0:a862:14fd/64 scope link
 valid_lft forever preferred_lft forever

```

这个系统上的两个接口 - 环回（`lo`）和网络（`enp0s25`）——显示了很多统计数据。 `lo` 接口显然是<ruby> 环回地址 <rt>  loolback </rt></ruby>。 我们可以在列表中看到环回 IPv4 地址（`127.0.0.1`）和环回 IPv6（`::1`）。 而普通的网络接口更有趣。

### 为什么是 enp0s25 而不是 eth0

如果你想知道为什么它在这个系统上被称为 `enp0s25`，而不是可能更熟悉的 `eth0`，那我们可以稍微解释一下。

新的命名方案被称为“<ruby> 可预测的网络接口 <rt>  Predictable Network Interface </rt></ruby>”。 它已经在基于systemd 的 Linux 系统上使用了一段时间了。 接口名称取决于硬件的物理位置。 `en` 仅仅就是 “ethernet” 的意思，就像 “eth” 用于对应 `eth0`，一样。 `p` 是以太网卡的总线编号，`s` 是插槽编号。 所以 `enp0s25` 告诉我们很多我们正在使用的硬件的信息。

`<BROADCAST,MULTICAST,UP,LOWER_UP>` 这个配置串告诉我们：

```
BROADCAST   该接口支持广播
MULTICAST   该接口支持多播
UP          网络接口已启用
LOWER_UP    网络电缆已插入，设备已连接至网络

```

列出的其他值也告诉了我们很多关于接口的知识，但我们需要知道 `brd` 和 `qlen` 这些词代表什么意思。 所以，这里显示的是上面展示的 `ip` 信息的其余部分的翻译。

```
mtu 1500                                    最大传输单位（数据包大小）为1,500字节
qdisc pfifo_fast                            用于数据包排队
state UP                                    网络接口已启用
group default                               接口组
qlen 1000                                   传输队列长度
link/ether 00:1e:4f:c8:43:fc                接口的 MAC（硬件）地址
brd ff:ff:ff:ff:ff:ff                       广播地址
inet 192.168.0.24/24                        IPv4 地址
brd 192.168.0.255                           广播地址
scope global                                全局有效
dynamic enp0s25                             地址是动态分配的
valid_lft 80866sec                          IPv4 地址的有效使用期限
preferred_lft 80866sec                      IPv4 地址的首选生存期
inet6 fe80::2c8e:1de0:a862:14fd/64          IPv6 地址
scope link                                  仅在此设备上有效
valid_lft forever                           IPv6 地址的有效使用期限
preferred_lft forever                       IPv6 地址的首选生存期

```

您可能已经注意到，`ifconfig` 命令提供的一些信息未包含在 `ip a` 命令的输出中 —— 例如传输数据包的统计信息。 如果您想查看发送和接收的数据包数量以及冲突数量的列表，可以使用以下 `ip` 命令：

```
$ ip -s link show enp0s25
2: enp0s25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
 link/ether 00:1e:4f:c8:43:fc brd ff:ff:ff:ff:ff:ff
 RX: bytes packets errors dropped overrun mcast
 224258568 418718 0 0 0 84376
 TX: bytes packets errors dropped carrier collsns
 6131373 78152 0 0 0 0

```

另一个 `ip` 命令提供有关系统路由表的信息。

```
$ ip route show
default via 192.168.0.1 dev enp0s25 proto static metric 100
169.254.0.0/16 dev enp0s25 scope link metric 1000
192.168.0.0/24 dev enp0s25 proto kernel scope link src 192.168.0.24 metric 100

```

`ip` 命令是非常通用的。 您可以从 `ip` 命令及其来自[Red Hat](https://access.redhat.com/sites/default/files/attachments/rh_ip_command_cheatsheet_1214_jcs_print.pdf)的选项获得有用的备忘单。

---

via: <https://www.networkworld.com/article/3262045/linux/checking-your-network-connections-on-linux.html>

作者：[Sandra Henry-Stocker](https://www.networkworld.com/author/Sandra-Henry_Stocker/) 译者：[Flowsnow](https://github.com/Flowsnow) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Zsync：一个仅下载文件新的部分的传输工具

# Zsync：一个仅下载文件新的部分的传输工具

就算是网费每天变得越来越便宜，你也不应该重复下载相同的东西来浪费你的流量。一个很好的例子就是下载 Ubuntu 或任何 Linux 镜像的开发版本。如你所知，Ubuntu 开发人员每隔几个月就会发布一次日常构建、alpha、beta 版 ISO 镜像以供测试。在过去，一旦发布我就会下载这些镜像，并审查每个版本。现在不用了！感谢 Zsync 文件传输程序。现在可以仅下载 ISO 镜像新的部分。这将为你节省大量时间和 Internet 带宽。不仅时间和带宽，它将为你节省服务端和客户端的资源。

Zsync 使用与 Rsync 相同的算法，如果你会得到一份已有文件旧版本，它只下载该文件新的部分。 Rsync 主要用于在计算机之间同步数据，而 Zsync 则用于分发数据。简单地说，可以使用 Zsync 将中心的一个文件分发给数千个下载者。它在 Artistic License V2 许可证下发布，完全免费且开源。

### 安装 Zsync

Zsync 在大多数 Linux 发行版的默认仓库中有。

在 Arch Linux 及其衍生版上，使用命令安装它：

```
$ sudo pacman -S zsync

```

在 Fedora 上，启用 Zsync 仓库：

```
$ sudo dnf copr enable ngompa/zsync

```

并使用命令安装它：

```
$ sudo dnf install zsync

```

在 Debian、Ubuntu、Linux Mint 上：

```
$ sudo apt-get install zsync

```

对于其他发行版，你可以从 [Zsync 下载页面](http://zsync.moria.org.uk/downloads)下载二进制打包文件，并手动编译安装它，如下所示。

```
$ wget http://zsync.moria.org.uk/download/zsync-0.6.2.tar.bz2
$ tar xjf zsync-0.6.2.tar.bz2
$ cd zsync-0.6.2/
$ configure
$ make
$ sudo make install

```

### 用法

请注意，只有当人们提供 zsync 下载方式时，zsync 才有用。目前，Debian、Ubuntu（所有版本）的 ISO 镜像都有 .zsync 下载链接。例如，请访问以下链接。

你可能注意到，Ubuntu 18.04 LTS 每日构建版有直接的 ISO 和 .zsync 文件。如果你下载 .ISO 文件，则必须在 ISO 更新时下载完整的 ISO 文件。但是，如果你下载的是 .zsync 文件，那么 Zsync 以后仅会下载新的更改。你不需要每次都下载整个 ISO 映像。

.zsync 文件包含 zsync 程序所需的元数据。该文件包含 rsync 算法的预先计算的校验和。它在服务器上生成一次，然后由任意数量的下载器使用。要使用 Zsync 客户端程序下载 .zsync 文件，你只需执行以下操作：

```
$ zsync <.zsync-file-URL>

```

例如：

```
$ zsync http://cdimage.ubuntu.com/ubuntu/daily-live/current/bionic-desktop-amd64.iso.zsync

```

如果你的系统中已有以前的镜像文件，那么 Zsync 将计算远程服务器中旧文件和新文件之间的差异，并仅下载新的部分。你将在终端看见计算过程一系列的点或星星。

如果你下载的文件的旧版本存在于当前工作目录，那么 Zsync 将只下载新的部分。下载完成后，你将看到两个镜像，一个你刚下载的镜像和以 .iso.zs-old 为扩展名的旧镜像。

如果没有找到相关的本地数据，Zsync 会下载整个文件。

你可以随时按 `CTRL-C` 取消下载过程。

试想一下，如果你直接下载 .ISO 文件或使用 torrent，每当你下载新镜像时，你将损失约 1.4GB 流量。因此，Zsync 不会下载整个 Alpha、beta 和日常构建映像，而只是在你的系统上下载了 ISO 文件的新部分，并在系统中有一个旧版本的拷贝。

今天就到这里。希望对你有帮助。我将很快另外写一篇有用的指南。在此之前，请保持关注！

干杯！

---

via: <https://www.ostechnix.com/zsync-file-transfer-utility-download-new-parts-file/>

作者：[SK](https://www.ostechnix.com/author/sk/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


如何安全地生成随机数

Summary: 太长了，懒得看：直接使用 urandom 吧。

太长了，懒得看：直接使用 urandom 吧。

# 如何安全地生成随机数

<img src="content_image/album_201803_25_103321odkv11vbjidznn8d.jpg" alt="" title="">

### 使用 urandom

使用 [urandom](http://blog.cr.yp.to/20140205-entropy.html)！使用 [urandom](http://cr.yp.to/talks/2011.09.28/slides.pdf)！使用 [urandom](http://golang.org/src/pkg/crypto/rand/rand_unix.go)！

使用 [urandom](http://security.stackexchange.com/questions/3936/is-a-rand-from-dev-urandom-secure-for-a-login-key)！使用 [urandom](http://stackoverflow.com/a/5639631)！使用 [urandom](https://twitter.com/bramcohen/status/206146075487240194)！

### 但对于密码学密钥呢？

仍然使用 [urandom](https://twitter.com/bramcohen/status/206146075487240194)。

### 为什么不是 SecureRandom、OpenSSL、havaged 或者 c 语言实现呢？

这些是用户空间的 CSPRNG（伪随机数生成器）。你应该用内核的 CSPRNG，因为：

* 内核可以访问原始设备熵。
* 它可以确保不在应用程序之间共享相同的状态。
* 一个好的内核 CSPRNG，像 FreeBSD 中的，也可以保证它播种之前不给你随机数据。

研究过去十年中的随机失败案例，你会看到一连串的用户空间的随机失败案例。[Debian 的 OpenSSH 崩溃](http://research.swtch.com/openssl)？用户空间随机！安卓的比特币钱包[重复 ECDSA 随机 k 值](http://arstechnica.com/security/2013/08/google-confirms-critical-android-crypto-flaw-used-in-5700-bitcoin-heist/)？用户空间随机！可预测洗牌的赌博网站？用户空间随机！

用户空间的生成器几乎总是依赖于内核的生成器。即使它们不这样做，整个系统的安全性也会确保如此。**但用户空间的 CSPRNG 不会增加防御深度；相反，它会产生两个单点故障。**

### 手册页不是说使用 /dev/random 嘛？

这个稍后详述，保留你的意见。你应该忽略掉手册页。不要使用 `/dev/random`。`/dev/random` 和 `/dev/urandom` 之间的区别是 Unix 设计缺陷。手册页不想承认这一点，因此它产生了一个并不存在的安全顾虑。把 `random(4)` 中的密码学上的建议当作传说，继续你的生活吧。

### 但是如果我需要的是真随机值，而非伪随机值呢？

urandom 和 `/dev/random` 提供的是同一类型的随机。与流行的观念相反，`/dev/random` 不提供“真正的随机”。从密码学上来说，你通常不需要“真正的随机”。

urandom 和 `/dev/random` 都基于一个简单的想法。它们的设计与流密码的设计密切相关：一个小秘密被延伸到不可预测值的不确定流中。 这里的秘密是“熵”，而流是“输出”。

只在 Linux 上 `/dev/random` 和 urandom 仍然有意义上的不同。Linux 内核的 CSPRNG 定期进行密钥更新（通过收集更多的熵）。但是 `/dev/random` 也试图跟踪内核池中剩余的熵，并且如果它没有足够的剩余熵时，偶尔也会罢工。这种设计和我所说的一样蠢；这与基于“密钥流”中剩下多少“密钥”的 AES-CTR 设计类似。

如果你使用 `/dev/random` 而非 urandom，那么当 Linux 对自己的 RNG（随机数生成器）如何工作感到困惑时，你的程序将不可预测地（或者如果你是攻击者，非常可预测地）挂起。使用 `/dev/random` 会使你的程序不太稳定，但这不会让你在密码学上更安全。

### 这是个缺陷，对吗？

不是，但存在一个你可能想要了解的 Linux 内核 bug，即使这并不能改变你应该使用哪一个 RNG。

在 Linux 上，如果你的软件在引导时立即运行，或者这个操作系统你刚刚安装好，那么你的代码可能会与 RNG 发生竞争。这很糟糕，因为如果你赢了竞争，那么你可能会在一段时间内从 urandom 获得可预测的输出。这是 Linux 中的一个 bug，如果你正在为 Linux 嵌入式设备构建平台级代码，那你需要了解它。

在 Linux 上，这确实是 urandom（而不是 `/dev/random`）的问题。这也是 [Linux 内核中的错误](https://factorable.net/weakkeys12.extended.pdf)。 但它也容易在用户空间中修复：在引导时，明确地为 urandom 提供种子。长期以来，大多数 Linux 发行版都是这么做的。但**不要**切换到不同的 CSPRNG。

### 在其它操作系统上呢？

FreeBSD 和 OS X 消除了 urandom 和 `/dev/random` 之间的区别；这两个设备的行为是相同的。不幸的是，手册页在解释为什么这样做上干的很糟糕，并延续了 Linux 上 urandom 可怕的神话。

无论你使用 `/dev/random` 还是 urandom，FreeBSD 的内核加密 RNG 都不会停摆。 除非它没有被提供种子，在这种情况下，这两者都会停摆。与 Linux 不同，这种行为是有道理的。Linux 应该采用它。但是，如果你是一名应用程序开发人员，这对你几乎没有什么影响：Linux、FreeBSD、iOS，无论什么：使用 urandom 吧。

### 太长了，懒得看

直接使用 urandom 吧。

### 结语

[ruby-trunk Feature #9569](https://bugs.ruby-lang.org/issues/9569)

>
> 现在，在尝试检测 `/dev/urandom` 之前，SecureRandom.random\_bytes 会尝试检测要使用的 OpenSSL。 我认为这应该反过来。在这两种情况下，你只需要将随机字节进行解压，所以 SecureRandom 可以跳过中间人（和第二个故障点），如果可用的话可以直接与 `/dev/urandom` 进行交互。
>
>
>

总结：

>
> `/dev/urandom` 不适合用来直接生成会话密钥和频繁生成其他应用程序级随机数据。
>
>
> GNU/Linux 上的 random(4) 手册所述......
>
>
>

感谢 Matthew Green、 Nate Lawson、 Sean Devlin、 Coda Hale 和 Alex Balducci 阅读了本文草稿。公正警告：Matthew 只是大多同意我的观点。

---

via: <https://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/>

作者：[Thomas & Erin Ptacek](https://sockpuppet.org/blog) 译者：[kimii](https://github.com/kimii) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出