2018年3月

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

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

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

消费类网络设备的供应商因制造了大混乱而臭名昭著。我回想起的第一件事发生在 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,它发布于 2017 年。

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

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

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

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

公共 NTP 服务器配置

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

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

配置一台公共的 NTP 服务器与配置一台用于局域网的 NTP 服务器是一样的,只需要几个配置。我们从阅读 协议规则 开始。遵守规则并注意你的行为;几乎每个时间服务器的维护者都是像你这样的志愿者。然后,从 StratumTwoTimeServers 中选择 4 到 7 个层级 2 的上游服务器。选择的时候,选取地理位置上靠近(小于 300 英里的)你的因特网服务提供商的上游服务器,阅读他们的访问规则,然后,使用 pingmtr 去找到延迟和跳数最小的服务器。

以下的 /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 申请加入池中。

查看官方的手册 分布式网络时间服务器(NTP) 学习所有的命令、配置选项、以及高级特性,比如,管理、查询、和验证。访问以下的站点学习关于运行一台时间服务器所需要的一切东西。

通过来自 Linux 基金会和 edX 的免费课程 “Linux 入门” 学习更多 Linux 的知识。


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

作者:CARLA SCHRODER 译者:qhwdw 校对:wxy

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

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

Tlog 包含三个工具,分别是 tlog-rec、tlog-rec-sessiontlog-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

完成这些安装后,我们可以下载该工具的源码包并根据需要将其解压到服务器上:

# 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 工作流程图

Tlog working process

首先,用户通过 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 是一个开源软件包,可用于实现集中式用户会话录制。它主要是作为一个更大的用户会话录制解决方案的一部分使用,但它被设计为独立且可重用的。该工具可以帮助录制用户所做的一切,并将其存储在服务器的某个位置,以备将来参考。你可以从这个文档中获得关于这个软件包使用的更多细节。我希望这篇文章对你有用。请发表你的宝贵建议和意见。

关于 Saheetha Shameer (作者)

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


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

作者:Saheetha Shameer 译者:geekpi 校对:wxy

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

Red 语言在其官网宣布,其于 2018 年 1 月在法国巴黎建立了基金会。Red 基金会托管在 法国高等研究实践学院(EPHE) ,由 François Jouen 所领导的“人与人工认知研究”部门所管理,François Jouen 是 Red 语言中著名的图像处理框架 RedCV 的作者。

基金会的职能如在其宣告RED 白皮书中所说,是管理整个 Red 开源项目,并使用 RED 通证来建立一个新的开源项目经济模式。为达成此目标,位于 GitHub 上的 Red 代码库中的所有版权拥有者都被要求将其权力让渡到基金会。而 Nenad 作为其源代码中最大的版权拥有者,将率先让渡(即修改源代码中的文件头和许可证文件)。

据 Red 基金会去年底发布的消息,Red 语言将发起多个支持区块链的子项目,包括用于智能合约编程的 Red/CCC,可以直接编译成支持以太坊虚拟机的字节码,也将会支持其它链,如 NEO;更小的运行时环境(大约 1mb,压缩后约 300kb)的 Red DApp,而采用 Electron) 框架的 DApp 需要 50 ~ 150 Mb。

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

  • 管理团队

    • Nenad Rakocevic,总裁
    • Francois Jouen,副总裁
    • Azouz Guizani,财务主管
  • Gregg Irwin 领导的运营团队。Peter W A Wood 是首位成员,将来还会有更多正式成员。
  • 由荣誉会员组成的顾问团队。

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

  • 基金会网站,功能包括:

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

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

此外,Red 基金会也在寻求合作伙伴,以实现其简化人类编程的愿景,特别是在区块链领域。目前大部分这些工作都由其合作伙伴如 NEO 委员会Enuma(一家领先的香港区块链服务公司)来完成。

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

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

简单测试

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

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

 title=

你应该看到与上面截图类似的输出。很有可能你会发现系统中至少有一个漏洞还存在。这的确是真的,因为 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。每个漏洞都有自己的部分。在这之间,脚本明确地告诉你是否受到这三个漏洞的影响。

 title=

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

这意味着什么

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


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

作者:Nick Congleton 译者:geekpi 校对:wxy

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

Plumbum:Shell 组合器

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

除了类似 shell 的语法便捷的快捷方式之外,该库还提供本地和远程命令执行(通过 SSH)、本地和远程文件系统路径、简单的工作目录和环境操作、快捷访问 ANSI 颜色,以及编程命令行接口(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"],你可以导入命令行

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

参见本地命令行

管道

>>> 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'

参见管道

重定向

>>> ((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'

参见输入/输出重定向

工作目录操作

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

参见路径本地对象

前台后和后台执行

>>> 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)>

参见前台和后台

命令行嵌套

>>> 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

参见命令行嵌套

远程命令(通过 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'

参见远程

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')

参见命令行应用程序

颜色和风格

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.

参见颜色

开发和安装

该库在 Github 上开发,非常乐意接受来自用户的补丁。请使用 GitHub 的内置 issue 跟踪器报告您遇到的任何问题或提出功能上的需求。该库在 IMIT 许可下发布。

要求

Plumbum 支持 Python 2.6-3.6 和 PyPy,并且通过 Travis CIAppveyor 持续地在 Linux,Mac 和 Windows 机器上测试。Plumbum 在任何类 Unix 的机器都应该可以正常工作,但是在 Windows 上,你也许需要安装一个合适的 coreutils 环境并把其加入到你的PATH环境变量中。我推荐 mingw(与 Windows Git 捆绑在一起),但是 cygwin 应该也可以。如果你仅仅是使用 Plumbum 代替 Popen 来运行 Windows 程序,那么就不需要 Unix 工具了。 注意远程命令的执行,你需要一个 openSHH 兼容的客户端(同样与 Windows Git 捆绑在一起)和一个 bash 兼容的 shell,也需要在主机上有一个 coreutils 环境。

下载

你可以在 Python Package Index (多种格式)下载该库,或者直接运行 pip install plumbum。如果你使用 Anaconda,你可以使用 conda install -c conda-forge plumbumconda-forge 通道获取。

用户指南

用户指南涵盖了 Plumbum 大部分功能,拥有大量的代码片段,你可以不用花多少时间即可开始使用。该指南逐渐介绍概念和"语法",因此推荐你按照顺序阅读。一个有效的快速参考指南略。。。

关于

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

致谢

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

Plumbum 也向 Rotem Yaari 致敬,他为特定的目的建议了一个代号为 pyplatform 的库,但是尚未实现过。

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

Fedora 和 Python —— 入门知识

Python 3.6 在 Fedora 中是默认安装的,它包含了 Python 的很多标准库。标准库提供了一些可以让我们的任务更加简单完成的模块的集合。例如,在我们的案例中,我们将使用 sqlite3 模块在数据库中去创建表、添加和读取数据。在这个案例中,我们试图去解决的是这样的一个特定问题,在标准库中没有包含,而有可能已经有人为我们开发了这样一个模块。最好是使用像大家熟知的 PyPI Python 包索引去搜索一下。在我们的示例中,我们将使用 feedparser 去解析 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 的新表。这个表有两个列 —— titledate —— 它们能存诸 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 命令去定义我们将要在哪个列上运行这个查询。我们使用 * 符号去选取所有列(titledate)。然后,我们使用查询的 WHERE 条件 article_titlearticle_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_titlearticle_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('[email protected]', '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'] = '[email protected]'
    msg['To'] = '[email protected]'
    smtp_server.send_message(msg)
    smtp_server.quit()

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

如果在你的 Gmail 帐户中使用了双因子认证,那么你需要配置一个密码应用程序为你的这个应用程序提供一个唯一密码。可以看这个 帮助页面

读取 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 的完整描述可以参考它的 文档

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 页面

总结

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

这个脚本在 GitHub 上可以找到。


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

作者:Clément Verna 译者:qhwdw 校对:wxy

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