分类 系统运维 下的文章

想要提升你的 DevOps 效率吗?将基础设施当成你的 CI 流程中的重要的一环。

持续交付(CD)和持续集成(CI)是 DevOps 的两个众所周知的方面。但在 CI 大肆流行的今天却忽略了另一个关键性的 I: 基础设施 infrastructure

曾经有一段时间 “基础设施”就意味着 无头 headless 的黑盒子、庞大的服务器,和高耸的机架 —— 更不用说漫长的采购流程和对盈余负载的错误估计。后来到了虚拟机时代,把基础设施处理得很好,虚拟化 —— 以前的世界从未有过这样。我们不再需要管理实体的服务器。仅仅是简单的点击,我们就可以创建和销毁、开始和停止、升级和降级我们的服务器。

有一个关于银行的流行故事:它们实现了数字化,并且引入了在线表格,用户需要手动填写表格、打印,然后邮寄回银行(LCTT 译注:我真的遇到过有人问我这样的需求怎么办)。这就是我们今天基础设施遇到的情况:使用新技术来做和以前一样的事情。

在这篇文章中,我们会看到在基础设施管理方面的进步,将基础设施视为一个版本化的组件并试着探索 不可变服务器 immutable server 的概念。在后面的文章中,我们将了解如何使用开源工具来实现持续的基础设施。

 title=

实践中的持续集成流程

这是我们熟悉的 CI,尽早发布、经常发布的循环流程。这个流程缺少一个关键的组件:基础设施。

突击小测试:

  • 你怎样创建和升级你的基础设施?
  • 你怎样控制和追溯基础设施的改变?
  • 你的基础设施是如何与你的业务进行匹配的?
  • 你是如何确保在正确的基础设施配置上进行测试的?

要回答这些问题,就要了解 持续基础设施 continuous infrastructure 。把 CI 构建流程分为 代码持续集成 continuous integration code (CIc)和 基础设施持续集成 continuous integration infrastructure (CIi)来并行开发和构建代码和基础设施,再将两者融合到一起进行测试。把基础设施构建视为 CI 流程中的重要的一环。

 title=

包含持续基础设施的 CI 流程

关于 CIi 定义的几个方面:

  1. 代码

通过代码来创建基础设施架构,而不是通过安装。 基础设施如代码 Infrastructure as code (IaC)是使用配置脚本创建基础设施的现代最流行的方法。这些脚本遵循典型的编码和单元测试周期(请参阅下面关于 Terraform 脚本的示例)。

  1. 版本

IaC 组件在源码仓库中进行版本管理。这让基础设施的拥有了版本控制的所有好处:一致性,可追溯性,分支和标记。

  1. 管理

通过编码和版本化的基础设施管理,你可以使用你所熟悉的测试和发布流程来管理基础设施的开发。

CIi 提供了下面的这些优势:

  1. 一致性 Consistency

版本化和标记化的基础设施意味着你可以清楚的知道你的系统使用了哪些组件和配置。这建立了一个非常好的 DevOps 实践,用来鉴别和管理基础设施的一致性。

  1. 可重现性 Reproducibility

通过基础设施的标记和基线,重建基础设施变得非常容易。想想你是否经常听到这个:“但是它在我的机器上可以运行!”现在,你可以在本地的测试平台中快速重现类似生产环境,从而将环境像变量一样在你的调试过程中删除。

  1. 可追溯性 Traceability

你是否还记得曾经有过多少次寻找到底是谁更改了文件夹权限的经历,或者是谁升级了 ssh 包?代码化的、版本化的,发布的基础设施消除了临时性变更,为基础设施的管理带来了可追踪性和可预测性。

  1. 自动化 Automation

借助脚本化的基础架构,自动化是下一个合乎逻辑的步骤。自动化允许你按需创建基础设施,并在使用完成后销毁它,所以你可以将更多宝贵的时间和精力用在更重要的任务上。

  1. 不变性 Immutability

CIi 带来了不可变基础设施等创新。你可以创建一个新的基础设施组件而不是通过升级(请参阅下面有关不可变设施的说明)。

持续基础设施是从运行基础环境到运行基础组件的进化。像处理代码一样,通过证实的 DevOps 流程来完成。对传统的 CI 的重新定义包含了缺少的那个 “i”,从而形成了连贯的 CD 。

(CIc + CIi) = CI -> CD

基础设施如代码 (IaC)

CIi 流程的一个关键推动因素是 基础设施如代码 infrastructure as code (IaC)。IaC 是一种使用配置文件进行基础设施创建和升级的机制。这些配置文件像其他的代码一样进行开发,并且使用版本管理系统进行管理。这些文件遵循一般的代码开发流程:单元测试、提交、构建和发布。IaC 流程拥有版本控制带给基础设施开发的所有好处,如标记、版本一致性,和修改可追溯。

这有一个简单的 Terraform 脚本用来在 AWS 上创建一个双层基础设施的简单示例,包括虚拟私有云(VPC)、弹性负载(ELB),安全组和一个 NGINX 服务器。Terraform 是一个通过脚本创建和更改基础设施架构和开源工具。

 title=

Terraform 脚本创建双层架构设施的简单示例

完整的脚本请参见 GitHub

不可变基础设施

你有几个正在运行的虚拟机,需要更新安全补丁。一个常见的做法是推送一个远程脚本单独更新每个系统。

要是不更新旧系统,如何才能直接丢弃它们并部署安装了新安全补丁的新系统呢?这就是 不可变基础设施 immutable infrastructure 。因为之前的基础设施是版本化的、标签化的,所以安装补丁就只是更新该脚本并将其推送到发布流程而已。

现在你知道为什么要说基础设施在 CI 流程中特别重要了吗?


via: https://opensource.com/article/17/11/continuous-infrastructure-other-ci

作者:Girish Managoli 选题:lujun9972 译者:Jamskr 校对:wxy

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

均衡网络流量的常用技术,它们的优势和利弊权衡。

大型的多站点互联网系统,包括内容分发网络(CDN)和云服务提供商,用一些方法来均衡来访的流量。这篇文章我们讲一下常见的流量均衡设计,包括它们的技术手段和利弊权衡。

早期的云计算服务提供商,可以提供单一一台客户 Web 服务器,分配一个 IP 地址,然后用一个便于人读的域名配置一个 DNS 记录指向这个 IP 地址,再将 IP 地址通过边界网关协议(BGP)宣告出去,BGP 是在不同网络之间交换路由信息的标准方式。

这本身并不是负载均衡,但是能在冗余的多条网络路径中进行流量分发,而且可以利用网络技术让流量绕过不可用的网络,从而提高了可用性(也引起了非对称路由的现象)。

简单的 DNS 负载均衡

随着来自客户的流量变大,老板希望服务是高可用的。你上线第二台 web 服务器,它有自己独立的公网 IP 地址,然后你更新了 DNS 记录,把用户流量引到两台服务器上(内心希望它们均衡地提供服务)。在其中一台服务器出故障之前,这样做一直是没有问题的。假设你能很快地监测到故障,可以更新一下 DNS 配置(手动更新或者通过软件)删除解析到故障机器的记录。

不幸的是,因为 DNS 记录会被缓存,在客户端缓存和它们依赖的 DNS 服务器上的缓存失效之前,大约一半的请求会失败。DNS 记录都有一个几分钟或更长的生命周期(TTL),所以这种方式会对系统可用性造成严重的影响。

更糟糕的是,部分客户端会完全忽略 TTL,所以有一些请求会持续被引导到你的故障机器上。设置很短的 TTL 也不是个好办法,因为这意味着更高的 DNS 服务负载,还有更长的访问时延,因为客户端要做更多的 DNS 查询。如果 DNS 服务由于某种原因不可用了,那设置更短的 TTL 会让服务的访问量更快地下降,因为没那么多客户端有你网站 IP 地址的缓存了。

增加网络负载均衡

要解决上述问题,可以增加一对相互冗余的四层(L4)网络负载均衡器,配置一样的虚拟 IP 地址(VIP)。均衡器可以是硬件的,也可以是像 HAProxy 这样的软件。域名的 DNS 记录指向 VIP,不再承担负载均衡的功能。

 title=

四层负载均衡器能够均衡用户和两台 web 服务器的连接

四层均衡器将网络流量均衡地引导至后端服务器。通常这是基于对 IP 数据包的五元组做散列(数学函数)来完成的,五元组包括:源地址、源端口、目的地址、目的端口、协议(比如 TCP 或 UDP)。这种方法是快速和高效的(还维持了 TCP 的基本属性),而且不需要均衡器维持每个连接的状态。(更多信息请阅读谷歌发表的 Maglev 论文,这篇论文详细讨论了四层软件负载均衡器的实现细节。)

四层均衡器可以对后端服务做健康检查,只把流量分发到健康的机器上。和使用 DNS 做负载均衡不同的是,在某个后端 web 服务故障的时候,它可以很快地把流量重新分发到其他机器上,虽然故障机器的已有连接会被重置。

当后端服务器的能力不同时,四层均衡器可以根据权重做流量分发。它为运维人员提供了强大的能力和灵活性,而且硬件成本相对较小。

扩展到多站点

系统规模在持续增长。你的客户希望能一直使用服务,即使是数据中心发生故障的时候。所以你建设了一个新的数据中心,另外独立部署了一套服务和四层负载均衡器集群,仍然使用同样的 VIP。DNS 的设置不变。

两个站点的边缘路由器都把自己的地址空间宣告出去,包括 VIP 地址。发往该 VIP 的请求可能到达任何一个站点,取决于用户和系统之间的网络是如何连接的,以及各个网络的路由策略是如何配置的。这就是泛播。大部分时候这种机制可以很好的工作。如果一个站点出问题了,你可以停止通过 BGP 宣告 VIP 地址,客户的请求就会迅速地转移到另外一个站点去。

 title=

多个站点使用泛播提供服务

这种设置有一些问题。最大的问题是,不能控制请求流向哪个站点,或者限制某个站点的流量。也没有一个明确的方式把用户的请求转到距离他最近的站点(为了降低网络延迟),不过,网络协议和路由选路配置在大部分情况下应该能把用户请求路由到最近的站点。

控制多站点系统中的入站请求

为了维持稳定性,需要能够控制每个站点的流量大小。要实现这种控制,可以给每个站点分配不同的 VIP 地址,然后用简单的或者有权重的 DNS 轮询来做负载均衡。

 title=

多站点提供服务,每个站点使用一个主 VIP,另外一个站点作为备份。基于能感知地理位置的 DNS。

现在有两个问题。

第一、使用 DNS 均衡意味着会有被缓存的记录,如果你要快速重定向流量的话就麻烦了。

第二、用户每次做新的 DNS 查询,都可能连上任意一个站点,可能不是距离最近的。如果你的服务运行在分布广泛的很多站点上,用户会感受到响应时间有明显的变化,取决于用户和提供服务的站点之间有多大的网络延迟。

让每个站点都配置上其他所有站点的 VIP 地址,并宣告出去(因此也会包含故障的站点),这样可以解决第一个问题。有一些网络上的小技巧,比如备份站点宣告路由时,不像主站点使用那么具体的目的地址,这样可以保证每个 VIP 的主站点只要可用就会优先提供服务。这是通过 BGP 来实现的,所以我们应该可以看到,流量在 BGP 更新后的一两分钟内就开始转移了。

即使离用户最近的站点是健康而且有服务能力的,但是用户真正访问到的却不一定是这个站点,这个问题还没有很好的解决方案。很多大型的互联网服务利用 DNS 给不同地域的用户返回不同的解析结果,也能有一定的效果。不过,因为网络地址的结构和地理位置无关,一个地址段也可能会改变所在位置(例如,当一个公司重新规划网络时),而且很多用户可能使用了同一个 DNS 缓存服务器。所以这种方案有一定的复杂度,而且容易出错。

增加七层负载均衡

又过了一段时间,你的客户开始要更多的高级功能。

虽然四层负载均衡可以高效地在多个 web 服务器之间分发流量,但是它们只针对源地址、目标地址、协议和端口来操作,请求的内容是什么就不得而知了,所以很多高级功能在四层负载均衡上实现不了。而七层(L7)负载均衡知道请求的内容和结构,所以能做更多的事情。

七层负载均衡可以实现缓存、限速、错误注入,做负载均衡时可以感知到请求的代价(有些请求需要服务器花更多的时间去处理)。

七层负载均衡还可以基于请求的属性(比如 HTTP cookies)来分发流量,可以终结 SSL 连接,还可以帮助防御应用层的拒绝服务(DoS)攻击。规模大的 L7 负载均衡的缺点是成本 —— 处理请求需要更多的计算,而且每个活跃的请求都占用一些系统资源。在一个或者多个 L7 均衡器前面运行 L4 均衡器集群,对扩展规模有帮助。

结论

负载均衡是一个复杂的难题。除了上面说过的策略,还有不同的负载均衡算法,用来实现负载均衡器的高可用技术、客户端负载均衡技术,以及最近兴起的服务网络等等。

核心的负载均衡模式随着云计算的发展而不断发展,而且,随着大型 web 服务商致力于让负载均衡技术更可控和更灵活,这项技术会持续发展下去。


via: https://opensource.com/article/18/10/internet-scale-load-balancing

作者:Laura Nolan 选题:lujun9972 译者:BeliteX 校对:wxy

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

如何为你的 SSH 服务器安装三种不同的双因子身份验证方案。

如今,安全比以往更加重要,保护 SSH 服务器是作为系统管理员可以做的最为重要的事情之一。传统地,这意味着禁用密码身份验证而改用 SSH 密钥。无疑这是你首先应该做的,但这并不意味着 SSH 无法变得更加安全。

双因子身份验证就是指需要两种身份验证才能登录。可以是密码和 SSH 密钥,也可以是密钥和第三方服务,比如 Google。这意味着单个验证方法的泄露不会危及服务器。

以下指南是为 SSH 启用双因子验证的三种方式。

当你修改 SSH 配置时,总是要确保有一个连接到服务器的第二终端。第二终端意味着你可以修复你在 SSH 配置中犯的任何错误。打开的终端将一直保持,即便 SSH 服务重启。

SSH 密钥和密码

SSH 支持对登录要求不止一个身份验证方法。

/etc/sh/sshd_config 中的 SSH 服务器配置文件中的 AuthenticationMethods 选项中设置了身份验证方法。

当在 /etc/ssh/sshd_config 中添加下一行时,SSH 需要提交一个 SSH 密钥,然后提示输入密码:

AuthenticationMethods "publickey,password"

如果你想要根据使用情况设置这些方法,那么请使用以下附加配置:

Match User jsmith
    AuthenticationMethods "publickey,password"

当你已经编辑或保存了新的 sshd_config 文件,你应该通过运行以下程序来确保你没有犯任何错误:

sshd -t

任何导致 SSH 不能启动的语法或其他错误都将在这里标记出来。当 ssh-t 运行时没有错误,使用 systemctl 重新启动 SSH:

systemctl restart sshd

现在,你可以使用新终端登录,以核实你会被提示输入密码并需要 SSH 密钥。如果你用 ssh-v,例如:

ssh -v [email protected]

你将可以看到登录的每一步。

注意,如果你确实将密码设置成必需的身份验证方法,你要确保将 PasswordAuthentication 选项设置成 yes

使用 Google Authenticator 的 SSH

Google 在 Google 自己的产品上使用的双因子身份验证系统可以集成到你的 SSH 服务器中。如果你已经使用了Google Authenticator,那么此方法将非常方便。

虽然 libpam-google-authenticator 是由 Google 编写的,但它是开源的。此外,Google Authenticator 是由 Google 编写的,但并不需要 Google 帐户才能工作。多亏了 Sitaram Chamarty 的贡献。

如果你还没有在手机上安装和配置 Google Authenticator,请参阅 这里的说明。

首先,我们需要在服务器上安装 Google Authenticatior 安装包。以下命令将更新你的系统并安装所需的软件包:

apt-get update
apt-get upgrade
apt-get install libpam-google-authenticator

现在,我们需要在你的手机上使用 Google Authenticatior APP 注册服务器。这是通过首先运行我们刚刚安装的程序完成的:

google-authenticator

运行这个程序时,会问到几个问题。你应该以适合你的设置的方式回答,然而,最安全的选项是对每个问题回答 y。如果以后需要更改这些选项,您可以简单地重新运行 google-authenticator 并选择不同的选项。

当你运行 google-authenticator 时,一个二维码会被打印到终端上,有些代码看起来像这样:

Your new secret key is: VMFY27TYDFRDNKFY
Your verification code is 259652
Your emergency scratch codes are:
  96915246
  70222983
  31822707
  25181286
  28919992

你应该将所有这些代码记录到一个像密码管理器一样安全的位置。“scratch codes” 是单一的使用代码,即使你的手机不可用,它总是允许你访问。

要将服务器注册到 Authenticator APP 中,只需打开应用程序并点击右下角的红色加号即可。然后选择扫描条码选项,扫描打印到终端的二维码。你的服务器和应用程序现在连接。

回到服务器上,我们现在需要编辑用于 SSH 的 PAM (可插入身份验证模块),以便它使用我们刚刚安装的身份验证器安装包。PAM 是独立系统,负责 Linux 服务器上的大多数身份验证。

需要修改的 SSH PAM 文件位于 /etc/pam.d/sshd ,用以下命令编辑:

nano /etc/pam.d/sshd

在文件顶部添加以下行:

auth required pam_google_authenticator.so

此外,我们还需要注释掉一行,这样 PAM 就不会提示输入密码。改变这行:

# Standard Un*x authentication.
@include common-auth

为如下:

# Standard Un*x authentication.
# @include common-auth

接下来,我们需要编辑 SSH 服务器配置文件:


nano /etc/ssh/sshd\_config “`


改变这一行:


ChallengeResponseAuthentication no


为:


ChallengeResponseAuthentication yes


 接下来,添加以下代码行来启用两个身份验证方案:SSH 密钥和谷歌认证器(键盘交互):


AuthenticationMethods "publickey,keyboard-interactive"


 在重新加载 SSH 服务器之前,最好检查一下在配置中没有出现任何错误。执行以下命令:


sshd -t


如果没有标识出任何错误,用新的配置重载 SSH:


systemctl reload sshd.service


 现在一切都应该开始工作了。现在,当你登录到你的服务器时,你将需要使用 SSH 密钥,并且当你被提示输入:


Verification code:


打开 Authenticator APP 并输入为您的服务器显示的 6 位代码。


### Authy


[Authy](https://authy.com/) 是一个双重身份验证服务,与 Google 一样,它提供基于时间的代码。然而,Authy 不需要手机,因为它提供桌面和平板客户端。它们还支持离线身份验证,不需要 Google 帐户。


你需要从应用程序商店安装 Authy 应用程序,或 Authy [下载页面](https://authy.com/download/)所链接的桌面客户端。


安装完应用程序后,需要在服务器上使用 API 密钥。这个过程需要几个步骤:


1. 在[这里](https://www.authy.com/signup)注册一个账户。
2. 向下滚动到 “Authy” 部分。
3. 在帐户上启用双因子认证(2FA)。
4. 回 “Authy” 部分。
5. 为你的服务器创建一个新的应用程序。
6. 从新应用程序的 “General Settings” 页面顶部获取 API 密钥。你需要 “PRODUCTION API KEY”旁边的眼睛符号来显示密钥。如图:


![](/data/attachment/album/201811/06/204801eiomcb42ngo2w8cn.png)


在某个安全的地方记下 API 密钥。


现在,回到服务器,以 root 身份运行以下命令:


curl -O 'https://raw.githubusercontent.com/authy/authy-ssh/master/authy-ssh'
bash authy-ssh install /usr/local/bin


 当提示时输入 API 键。如果输入错误,你始终可以编辑 `/usr/local/bin/authy-ssh` 再添加一次。


Authy 现已安装。但是,在为用户启用它之前,它不会开始工作。启用 Authy 的命令有以下形式:


/usr/local/bin/authy-ssh enable


 root 登录的一些示例细节:


/usr/local/bin/authy-ssh enable root [email protected] 44 20822536476


 如果一切顺利,你会看到:


User was registered


现在可以通过运行以下命令来测试 Authy:


authy-ssh test


最后,重载 SSH 实现新的配置:


systemctl reload sshd.service


 Authy 现在正在工作,SSH 需要它才能登录。


现在,当你登录时,你将看到以下提示:


Authy Token (type 'sms' to request a SMS token):


 你可以输入手机或桌面客户端的 Authy APP 上的代码。或者你可以输入 `sms`, Authy 会给你发送一条带有登录码的短信。


可以通过运行以下命令卸载 Authy:


/usr/local/bin/authy-ssh uninstall




---


via: <https://bash-prompt.net/guides/ssh-2fa/>


作者:[Elliot Cooper](https://bash-prompt.net) 译者:[cielllll](https://github.com/cielllll) 校对:[wxy](https://github.com/wxy)

学习使用 systemd 创建启动你的游戏服务器的定时器。

之前,我们看到了如何手动的在开机与关机时在启用某个设备时在文件系统发生改变时 启用与禁用 systemd 服务。

定时器增加了另一种启动服务的方式,基于……时间。尽管与定时任务很相似,但 systemd 定时器稍微地灵活一些。让我们看看它是怎么工作的。

“定时运行”

让我们展开本系列前两篇文章你所设置的 Minetest 服务器作为如何使用定时器单元的第一个例子。如果你还没有读过那几篇文章,可以现在去看看。

你将通过创建一个定时器来“改进” Minetest 服务器,使得在服务器启动 1 分钟后运行游戏服务器而不是立即运行。这样做的原因可能是,在启动之前可能会用到其他的服务,例如发邮件给其他玩家告诉他们游戏已经准备就绪,你要确保其他的服务(例如网络)在开始前完全启动并运行。

最终,你的 minetest.timer 单元看起来就像这样:

# minetest.timer
[Unit]
Description=Runs the minetest.service 1 minute after boot up

[Timer]
OnBootSec=1 m
Unit=minetest.service

[Install]
WantedBy=basic.target

一点也不难吧。

如以往一般,开头是 [Unit] 和一段描述单元作用的信息,这儿没什么新东西。[Timer] 这一节是新出现的,但它的作用不言自明:它包含了何时启动服务,启动哪个服务的信息。在这个例子当中,OnBootSec 是告诉 systemd 在系统启动后运行服务的指令。

其他的指令有:

  • OnActiveSec=,告诉 systemd 在定时器启动后多长时间运行服务。
  • OnStartupSec=,同样的,它告诉 systemd 在 systemd 进程启动后多长时间运行服务。
  • OnUnitActiveSec=,告诉 systemd 在上次由定时器激活的服务启动后多长时间运行服务。
  • OnUnitInactiveSec=,告诉 systemd 在上次由定时器激活的服务停用后多长时间运行服务。

继续 minetest.timer 单元,basic.target 通常用作 后期引导服务 late boot services 同步点 synchronization point 。这就意味着它可以让 minetest.timer 单元运行在安装完 本地挂载点 local mount points 或交换设备,套接字、定时器、路径单元和其他基本的初始化进程之后。就像在第二篇文章中 systemd 单元里解释的那样,targets 就像 旧的运行等级 old run levels 一样,可以将你的计算机置于某个状态,或像这样告诉你的服务在达到某个状态后开始运行。

在前两篇文章中你配置的 minetest.service 文件最终看起来就像这样:

# minetest.service
[Unit]
Description= Minetest server
Documentation= https://wiki.minetest.net/Main_Page

[Service]
Type= simple
User=

ExecStart= /usr/games/minetest --server
ExecStartPost= /home//bin/mtsendmail.sh "Ready to rumble?" "Minetest Starting up"

TimeoutStopSec= 180
ExecStop= /home//bin/mtsendmail.sh "Off to bed. Nightie night!" "Minetest Stopping in 2 minutes"
ExecStop= /bin/sleep 120
ExecStop= /bin/kill -2 $MAINPID

[Install]
WantedBy= multi-user.target

这儿没什么需要修改的。但是你需要将 mtsendmail.sh(发送你的 email 的脚本)从:

#!/bin/bash
# mtsendmail
sleep 20
echo $1 | mutt -F /home/<username>/.muttrc -s "$2" my_minetest@mailing_list.com
sleep 10

改成:

#!/bin/bash
# mtsendmail.sh
echo $1 | mutt -F /home/paul/.muttrc -s "$2" [email protected]

你做的事是去除掉 Bash 脚本中那些蹩脚的停顿。Systemd 现在来做等待。

让它运行起来

确保一切运作正常,禁用 minetest.service

sudo systemctl disable minetest

这使得系统启动时它不会一同启动;然后,相反地,启用 minetest.timer

sudo systemctl enable minetest.timer

现在你就可以重启服务器了,当运行 sudo journalctl -u minetest.* 后,你就会看到 minetest.timer 单元执行后大约一分钟,minetest.service 单元开始运行。

 title=

图 1:minetest.timer 运行大约 1 分钟后 minetest.service 开始运行

时间的问题

minetest.timer 在 systemd 的日志里显示的启动时间为 09:08:33 而 minetest.service 启动时间是 09:09:18,它们之间少于 1 分钟,关于这件事有几点需要说明一下:首先,请记住我们说过 OnBootSec= 指令是从引导完成后开始计算服务启动的时间。当 minetest.timer 的时间到来时,引导已经在几秒之前完成了。

另一件事情是 systemd 给自己设置了一个 误差幅度 margin of error (默认是 1 分钟)来运行东西。这有助于在多个 资源密集型进程 resource-intensive processes 同时运行时分配负载:通过分配 1 分钟的时间,systemd 可以等待某些进程关闭。这也意味着 minetest.service 会在引导完成后的 1~2 分钟之间启动。但精确的时间谁也不知道。

顺便一提,你可以用 AccuracySec= 指令修改误差幅度

你也可以检查系统上所有的定时器何时运行或是上次运行的时间:

systemctl list-timers --all

 title=

图 2:检查定时器何时运行或上次运行的时间

最后一件值得思考的事就是你应该用怎样的格式去表示一段时间。Systemd 在这方面非常灵活:2 h2 hours2hr 都可以用来表示 2 个小时。对于“秒”,你可以用 secondssecondsecs。“分”也是同样的方式:minutesminuteminm。你可以检查 man systemd.time 来查看 systemd 能够理解的所有时间单元。

下一次

下次你会看到如何使用日历中的日期和时间来定期运行服务,以及如何通过组合定时器与设备单元在插入某些硬件时运行服务。

回头见!

在 Linux 基金会和 edx 上通过免费课程 “Introduction to Linux” 学习更多关于 Linux 的知识。


via: https://www.linux.com/blog/learn/intro-to-linux/2018/7/setting-timer-systemd-linux

作者:Paul Brown 选题:lujun9972 译者:LuuMing 校对:wxy

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

如何在流行而强大的 Apache Web 服务器上托管两个或多个站点。

在我的上一篇文章中,我解释了如何为单个站点配置 Apache Web 服务器,事实证明这很容易。在这篇文章中,我将向你展示如何使用单个 Apache 实例来服务多个站点。

注意:我写这篇文章的环境是 Fedora 27 虚拟机,配置了 Apache 2.4.29。如果你用另一个发行版或不同的 Fedora 版本,那么你使用的命令以及配置文件的位置和内容可能会有所不同。

正如我之前的文章中提到的,Apache 的所有配置文件都位于 /etc/httpd/conf/etc/httpd/conf.d。默认情况下,站点的数据位于 /var/www 中。对于多个站点,你需要提供多个位置,每个位置对应托管的站点。

基于名称的虚拟主机

使用基于名称的虚拟主机,你可以为多个站点使用一个 IP 地址。现代 Web 服务器,包括 Apache,使用指定 URL 的 hostname 部分来确定哪个虚拟 Web 主机响应页面请求。这仅仅需要比一个站点更多的配置。

即使你只从单个站点开始,我也建议你将其设置为虚拟主机,这样可以在以后更轻松地添加更多站点。在本文中,我将从上一篇文章中我们停止的地方开始,因此你需要设置原来的站点,即基于名称的虚拟站点。

准备原来的站点

在设置第二个站点之前,你需要为现有网站提供基于名称的虚拟主机。如果你现在没有站点,请返回并立即创建一个

一旦你有了站点,将以下内容添加到 /etc/httpd/conf/httpd.conf 配置文件的底部(添加此内容是你需要对 httpd.conf 文件进行的唯一更改):

<VirtualHost 127.0.0.1:80>
    DocumentRoot /var/www/html
    ServerName www.site1.org
</VirtualHost>

这将是第一个虚拟主机配置节,它应该保持为第一个,以使其成为默认定义。这意味着通过 IP 地址或解析为此 IP 地址但没有特定命名主机配置节的其它名称对服务器的 HTTP 访问将定向到此虚拟主机。所有其它虚拟主机配置节都应跟在此节之后。

你还需要使用 /etc/hosts 中的条目设置你的网站以提供名称解析。上次,我们只使用了 localhost 的 IP 地址。通常,这可以使用你使用的任何名称服务来完成,例如 Google 或 Godaddy。对于你的测试网站,通过在 /etc/hosts 中的 localhost 行添加一个新名称来完成此操作。添加两个网站的条目,方便你以后不需再次编辑此文件。结果如下:

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 www.site1.org www.site2.org

让我们将 /var/www/html/index.html 文件改变得更加明显一点。它应该看起来像这样(带有一些额外的文本来识别这是站点 1):

<h1>Hello World</h1>

Web site 1.

重新启动 HTTPD 服务器,已启用对 httpd 配置的更改。然后,你可以从命令行使用 Lynx 文本模式查看网站。

[root@testvm1 ~]# systemctl restart httpd
[root@testvm1 ~]# lynx www.site1.org

                                              Hello World 
  Web site 1.
<snip>
Commands: Use arrow keys to move, '?' for help, 'q' to quit, '<-' to go back.
Arrow keys: Up and Down to move.  Right to follow a link; Left to go back.
H)elp O)ptions P)rint G)o M)ain screen Q)uit /=search [delete]=history list

你可以看到原始网站的修改内容,没有明显的错误,先按下 Q 键,然后按 Y 退出 Lynx Web 浏览器。

配置第二个站点

现在你已经准备好建立第二个网站。使用以下命令创建新的网站目录结构:

[root@testvm1 html]# mkdir -p /var/www/html2

注意,第二个站点只是第二个 html 目录,与第一个站点位于同一 /var/www 目录下。

现在创建一个新的索引文件 /var/www/html2/index.html,其中包含以下内容(此索引文件稍有不同,以区别于原来的网站):

<h1>Hello World -- Again</h1>

Web site 2.

httpd.conf 中为第二个站点创建一个新的配置节,并将其放在上一个虚拟主机配置节下面(这两个应该看起来非常相似)。此节告诉 Web 服务器在哪里可以找到第二个站点的 HTML 文件。

<VirtualHost 127.0.0.1:80>
    DocumentRoot /var/www/html2
    ServerName www.site2.org
</VirtualHost>

重启 HTTPD,并使用 Lynx 来查看结果。

[root@testvm1 httpd]# systemctl restart httpd
[root@testvm1 httpd]# lynx www.site2.org

                                    Hello World -- Again

   Web site 2.

<snip>
Commands: Use arrow keys to move, '?' for help, 'q' to quit, '<-' to go back.
Arrow keys: Up and Down to move.  Right to follow a link; Left to go back.
H)elp O)ptions P)rint G)o M)ain screen Q)uit /=search [delete]=history list

在这里,我压缩了输出结果以适应这个空间。页面的差异表明这是第二个站点。要同时显示两个站点,请打开另一个终端会话并使用 Lynx Web 浏览器查看另一个站点。

其他考虑

这个简单的例子展示了如何使用 Apache HTTPD 服务器的单个实例来服务于两个站点。当考虑其他因素时,配置虚拟主机会变得有点复杂。

例如,你可能希望为这些网站中的一个或全部使用一些 CGI 脚本。为此,你可能为 CGI 程序在 /var/www 目录下创建一些目录:/var/www/cgi-bin/var/www/cgi-bin2,以与 HTML 目录命名一致。然后,你需要将配置指令添加到虚拟主机节,以指定 CGI 脚本的目录位置。每个站点可以有下载文件的目录。这还需要相应虚拟主机节中的条目。

Apache 网站描述了管理多个站点的其他方法,以及从性能调优到安全性的配置选项。

Apache 是一个强大的 Web 服务器,可以用来管理从简单到高度复杂的网站。尽管其总体市场份额在缩小,但它仍然是互联网上最常用的 HTTPD 服务器。


via: https://opensource.com/article/18/3/configuring-multiple-web-sites-apache

作者:David Both 译者:MjSeven 校对:wxy

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

iptables 是一款控制系统进出流量的强大配置工具。

现代 Linux 内核带有一个叫 Netfilter 的数据包过滤框架。Netfilter 提供了允许、丢弃以及修改等操作来控制进出系统的流量数据包。基于 Netfilter 框架的用户层命令行工具 iptables 提供了强大的防火墙配置功能,允许你添加规则来构建防火墙策略。iptables 丰富复杂的功能以及其巴洛克式命令语法可能让人难以驾驭。我们就来探讨一下其中的一些功能,提供一些系统管理员解决某些问题需要的使用技巧。

避免封锁自己

应用场景:假设你将对公司服务器上的防火墙规则进行修改,你需要避免封锁你自己以及其他同事的情况(这将会带来一定时间和金钱的损失,也许一旦发生马上就有部门打电话找你了)

技巧 #1: 开始之前先备份一下 iptables 配置文件。

用如下命令备份配置文件:

/sbin/iptables-save > /root/iptables-works

技巧 #2: 更妥当的做法,给文件加上时间戳。

用如下命令加时间戳:

/sbin/iptables-save > /root/iptables-works-`date +%F`

然后你就可以生成如下名字的文件:

/root/iptables-works-2018-09-11

这样万一使得系统不工作了,你也可以很快的利用备份文件恢复原状:

/sbin/iptables-restore < /root/iptables-works-2018-09-11

技巧 #3: 每次创建 iptables 配置文件副本时,都创建一个指向最新的文件的链接。

ln –s /root/iptables-works-`date +%F` /root/iptables-works-latest

技巧 #4: 将特定规则放在策略顶部,底部放置通用规则。

避免在策略顶部使用如下的一些通用规则:

iptables -A INPUT -p tcp --dport 22 -j DROP

你在规则中指定的条件越多,封锁自己的可能性就越小。不要使用上面非常通用的规则,而是使用如下的规则:

iptables -A INPUT -p tcp --dport 22 –s 10.0.0.0/8 –d 192.168.100.101 -j DROP

此规则表示在 INPUT 链尾追加一条新规则,将源地址为 10.0.0.0/8、 目的地址是 192.168.100.101、目的端口号是 22--dport 22 ) 的 TCP(-p tcp )数据包通通丢弃掉。

还有很多方法可以设置更具体的规则。例如,使用 -i eth0 将会限制这条规则作用于 eth0 网卡,对 eth1 网卡则不生效。

技巧 #5: 在策略规则顶部将你的 IP 列入白名单。

这是一个有效地避免封锁自己的设置:

iptables -I INPUT -s <your IP> -j ACCEPT

你需要将该规则添加到策略首位置。-I 表示则策略首部插入规则,-A 表示在策略尾部追加规则。

技巧 #6: 理解现有策略中的所有规则。

不犯错就已经成功了一半。如果你了解 iptables 策略背后的工作原理,使用起来更为得心应手。如果有必要,可以绘制流程图来理清数据包的走向。还要记住:策略的预期效果和实际效果可能完全是两回事。

设置防火墙策略

应用场景:你希望给工作站配置具有限制性策略的防火墙。

技巧 #1: 设置默认规则为丢弃

# Set a default policy of DROP
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]

技巧 #2: 将用户完成工作所需的最少量服务设置为允许

该策略需要允许工作站能通过 DHCP(-p udp --dport 67:68 -sport 67:68)来获取 IP 地址、子网掩码以及其他一些信息。对于远程操作,需要允许 SSH 服务(-dport 22),邮件服务(--dport 25),DNS 服务(--dport 53),ping 功能(-p icmp),NTP 服务(--dport 123 --sport 123)以及 HTTP 服务(-dport 80)和 HTTPS 服务(--dport 443)。

# Set a default policy of DROP
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]

# Accept any related or established connections
-I INPUT  1 -m state --state RELATED,ESTABLISHED -j ACCEPT
-I OUTPUT 1 -m state --state RELATED,ESTABLISHED -j ACCEPT

# Allow all traffic on the loopback interface
-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT

# Allow outbound DHCP request
-A OUTPUT –o eth0 -p udp --dport 67:68 --sport 67:68 -j ACCEPT

# Allow inbound SSH
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -m state --state NEW  -j ACCEPT

# Allow outbound email
-A OUTPUT -i eth0 -p tcp -m tcp --dport 25 -m state --state NEW  -j ACCEPT

# Outbound DNS lookups
-A OUTPUT -o eth0 -p udp -m udp --dport 53 -j ACCEPT

# Outbound PING requests
-A OUTPUT –o eth0 -p icmp -j ACCEPT

# Outbound Network Time Protocol (NTP) requests
-A OUTPUT –o eth0 -p udp --dport 123 --sport 123 -j ACCEPT

# Outbound HTTP
-A OUTPUT -o eth0 -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT
-A OUTPUT -o eth0 -p tcp -m tcp --dport 443 -m state --state NEW -j ACCEPT

COMMIT

限制 IP 地址范围

应用场景:贵公司的 CEO 认为员工在 Facebook 上花费过多的时间,需要采取一些限制措施。CEO 命令下达给 CIO,CIO 命令 CISO,最终任务由你来执行。你决定阻止一切到 Facebook 的访问连接。首先你使用 host 或者 whois 命令来获取 Facebook 的 IP 地址。

host -t a www.facebook.com
www.facebook.com is an alias for star.c10r.facebook.com.
star.c10r.facebook.com has address 31.13.65.17
whois 31.13.65.17 | grep inetnum
inetnum:        31.13.64.0 - 31.13.127.255

然后使用 CIDR 到 IPv4 转换 页面来将其转换为 CIDR 表示法。然后你得到 31.13.64.0/18 的地址。输入以下命令来阻止对 Facebook 的访问:

iptables -A OUTPUT -p tcp -i eth0 –o eth1 –d 31.13.64.0/18 -j DROP

按时间规定做限制 - 场景1

应用场景:公司员工强烈反对限制一切对 Facebook 的访问,这导致了 CEO 放宽了要求(考虑到员工的反对以及他的助理提醒说她负责更新他的 Facebook 页面)。然后 CEO 决定允许在午餐时间访问 Facebook(中午 12 点到下午 1 点之间)。假设默认规则是丢弃,使用 iptables 的时间功能便可以实现。

iptables –A OUTPUT -p tcp -m multiport --dport http,https -i eth0 -o eth1 -m time --timestart 12:00 –timestop 13:00 –d 31.13.64.0/18 -j ACCEPT

该命令中指定在中午12点(--timestart 12:00)到下午 1 点(--timestop 13:00)之间允许(-j ACCEPT)到 Facebook.com (-d [31.13.64.0/18][5])的 http 以及 https (-m multiport --dport http,https)的访问。

按时间规定做限制 - 场景2

应用场景:在计划系统维护期间,你需要设置凌晨 2 点到 3 点之间拒绝所有的 TCP 和 UDP 访问,这样维护任务就不会受到干扰。使用两个 iptables 规则可实现:

iptables -A INPUT -p tcp -m time --timestart 02:00 --timestop 03:00 -j DROP
iptables -A INPUT -p udp -m time --timestart 02:00 --timestop 03:00 -j DROP

该规则禁止(-j DROP)在凌晨2点(--timestart 02:00)到凌晨3点(--timestop 03:00)之间的 TCP 和 UDP (-p tcp and -p udp)的数据进入(-A INPUT)访问。

限制连接数量

应用场景:你的 web 服务器有可能受到来自世界各地的 DoS 攻击,为了避免这些攻击,你可以限制单个 IP 地址到你的 web 服务器创建连接的数量:

iptables –A INPUT –p tcp –syn -m multiport -–dport http,https –m connlimit -–connlimit-above 20 –j REJECT -–reject-with-tcp-reset

分析一下上面的命令。如果单个主机在一分钟之内新建立(-p tcp -syn)超过 20 个(-connlimit-above 20)到你的 web 服务器(--dport http,https)的连接,服务器将拒绝(-j REJECT)建立新的连接,然后通知对方新建连接被拒绝(--reject-with-tcp-reset)。

监控 iptables 规则

应用场景:由于数据包会遍历链中的规则,iptables 遵循 “首次匹配获胜” 的原则,因此经常匹配的规则应该靠近策略的顶部,而不太频繁匹配的规则应该接近底部。 你怎么知道哪些规则使用最多或最少,可以在顶部或底部附近监控?

技巧 #1: 查看规则被访问了多少次

使用命令:

iptables -L -v -n –line-numbers

-L 选项列出链中的所有规则。因为没有指定具体哪条链,所有链规则都会被输出,使用 -v 选项显示详细信息,-n 选项则显示数字格式的数据包和字节计数器,每个规则开头的数值表示该规则在链中的位置。

根据数据包和字节计数的结果,你可以将访问频率最高的规则放到顶部,将访问频率最低的规则放到底部。

技巧 #2: 删除不必要的规则

哪条规则从来没有被访问过?这些可以被清除掉。用如下命令查看:

iptables -nvL | grep -v "0     0"

注意:两个数字 0 之间不是 Tab 键,而是 5 个空格。

技巧 #3: 监控正在发生什么

可能你也想像使用 top 命令一样来实时监控 iptables 的情况。使用如下命令来动态监视 iptables 中的活动,并仅显示正在遍历的规则:

watch --interval=5 'iptables -nvL | grep -v "0     0"'

watch 命令通过参数 iptables -nvL | grep -v “0 0“ 每隔 5 秒输出 iptables 的动态。这条命令允许你查看数据包和字节计数的变化。

输出日志

应用场景:经理觉得你这个防火墙员工的工作质量杠杠的,但如果能有网络流量活动日志最好了。有时候这比写一份有关工作的报告更有效。

使用工具 FWLogwatch 基于 iptables 防火墙记录来生成日志报告。FWLogwatch 工具支持很多形式的报告并且也提供了很多分析功能。它生成的日志以及月报告使得管理员可以节省大量时间并且还更好地管理网络,甚至减少未被注意的潜在攻击。

这里是一个 FWLogwatch 生成的报告示例:

不要满足于允许和丢弃规则

本文中已经涵盖了 iptables 的很多方面,从避免封锁自己、配置 iptables 防火墙以及监控 iptables 中的活动等等方面介绍了 iptables。你可以从这里开始探索 iptables 甚至获取更多的使用技巧。


via: https://opensource.com/article/18/10/iptables-tips-and-tricks

作者:Gary Smith 选题:lujun9972 译者:jrg 校对:wxy

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