2. 启动并运行 Varnish

本节介绍启动、运行和停止 Varnish、命令行标志和选项、与正在运行的 Varnish 进程通信、配置存储和套接字以及保护 Varnish 免受攻击。

2.1 安全第一

如果您是唯一参与运行 Varnish 的人,或者所有相关人员都受到相同程度的信任,则可以跳过本章。我们已经尽可能地保护 Varnish 免受任何可以通过 HTTP 套接字进入的东西的影响。

如果您的网络基础设施的一部分是外包的或以其他方式按照管理路线划分的,您需要考虑安全性。

Varnish 提供了四个级别的权限,大致与控制进入 Varnish 的方式和位置相关:

Varnish 提供了四个级别的权限,大致与控制进入 Varnish 的方式和位置相关:

  1. 命令行参数
  2. CLI 界面,
  3. VCL 程序
  4. HTTP 请求

2.1.1 命令行参数

顶级安全决策是在以命令行参数的形式启动 Varnish 时决定和定义的,我们使用此策略是为了使它们免受后续操作的影响。

需要做出的重要决定是:

  1. 谁应该有权访问命令行界面?

  2. 他们可以改变哪些参数?

  3. 是否允许内联 C 代码?

  4. VMOD 是否/如何受到限制?

  5. 子进程如何会被监禁?

CLI 界面访问

可以通过三种方式访问​​命令行界面。

varnishd可以被告知监听 TCP 套接字并提供 CLI 连接。您可以将套接字绑定到内核可接受的几乎任何内容:

-T 127.0.0.1:631
-T localhost:9999
-T 192.168.1.1:34
-T '[fe80::1]:8082'

默认情况下,它将选择一个随机端口号,varnishadm(8)可以从共享内存中学习该端口号。-T localhost:0

通过使用“localhost”地址,您可以限制对本地计算机的 CLI 访问。

您还可以将 CLI 端口绑定到可通过网络访问的 IP 地址,并让其他计算机直接连接。

这不会给您带来任何保密性,即 CLI 命令将以不加密的 ASCII 文本形式通过网络,但 -S/PSK 身份验证要求远程端知道共享秘密。

或者,您可以将 CLI 端口绑定到“localhost”地址,并使用 ssh/VPN 或类似工具通过与本地计算机的安全连接为远程用户提供访问权限。

如果您使用ssh,您可以限制每个用户只能执行varnishadm 的命令,甚至可以使用varnishadm 的包装脚本 来允许特定的 CLI 命令。

还可以使用“-M”参数将varnishd配置为“反向模式”。在这种情况下,varnishd将尝试打开到指定地址的 TCP 连接,并启动到中央 Varnish 管理设施的 CLI 连接。

这种情况下的连接也没有加密,但远程端仍必须使用 -S/PSK 进行身份验证。

最后,如果您使用“-d”选项运行 varnishd,您将在 stdin/stdout 上获得 CLI 命令,但既然您启动了该过程,就很难阻止您获得 CLI 访问权限,不是吗?

CLI 接口身份验证

默认情况下,CLI 界面受到简单但功能强大的“预共享密钥”身份验证方法的保护,该方法不提供保密性(即:CLI 命令和响应未加密)。

-S/PSK 的工作方式非常简单:在启动过程中,会创建一个包含随机内容的文件,并且该文件只能由启动varnishd的用户(或超级用户)访问。

要验证和使用 CLI 连接,您需要知道该文件的内容,以便回答加密质询varnishd问题,请参阅身份验证 CLI 连接

varnishadm使用所有这些来限制访问,它只有在可以读取秘密文件的情况下才会起作用。

如果您希望允许其他用户(本地或远程)能够访问 CLI 连接,您必须创建自己的秘密文件并允许(仅!)这些用户读取它。

创建秘密文件的一个好方法是:

dd if=/dev/random of=/etc/varnish_secret count=1

当您启动varnishd时,您可以使用“-S”指定文件名,并且不用说varnishd主进程也需要能够读取该文件。

您可以在varnishd运行时更改秘密文件的内容 ,每次对 CLI 连接进行身份验证时都会读取该文件。

在本地系统上,varnishadm可以从共享内存中检索文件名,但在远程系统上,您需要使用 -S 参数为varnishadm提供 秘密文件的副本。

如果要禁用 -S/PSK 身份验证,请为 varnishd 指定带有空参数的“-S”:

varnishd [...] -S "" [...]

参数

参数可以从命令行设置,并设置为“只读”(使用“-r”),因此随后无法从 CLI 界面修改它们。

几乎任何参数都可以用来完全搞乱你的 HTTP 服务,但其中一些参数可能比其他参数造成更大的损害:

cc_命令

执行任意程序

vcc_allow_inline_c

允许 VCL 中内联 C,这将允许 Varnish 执行 VCL 中的任何 C 代码。

此外,您可能需要查看并锁定:

syslog_cli_traffic

将所有 CLI 命令记录到syslog(8),以便您知道发生了什么。

vcc_不安全_路径

将 VCL/VMOD 限制为vcl_pathvmod_path

vmod_路径

Varnish 将在其中查找模块的目录(或冒号分隔的目录列表)。这可能会被用来将恶意模块加载到 Varnish 中。

2.1.2 CLI 界面

Varnish中的CLI界面非常强大,如果你能够访问CLI界面,你几乎可以对Varnish进程做任何事情。

如上所述,可以通过限制某些参数来限制某些损害,但这只会保护本地文件系统和操作系统,而不会保护您的 HTTP 服务。

我们目前没有办法将特定 CLI 命令限制为特定 CLI 连接。获得这种效果的一种方法是将所有 CLI 访问“包装”在使用varnishadm(1)的预先批准的脚本中

提交经过清理的 CLI 命令,并将远程用户限制为只能使用这些脚本,例如使用 sshd(8) 的配置。

2.1.3 VCL 程序

VCL 代码中有两种“危险”机制:VMOD 和内联 C。

这两种机制都允许执行任意代码,因此允许一个人以子进程的权限访问机器。

如果varnishd以 root/超级用户身份启动,我们将使用操作系统上可用的任何工具对子进程进行沙箱处理,但如果varnishd不是以 root/超级用户身份启动,则这是不可能的。不,不要问我为什么你必须成为超级用户才能降低子进程的权限…

从 Varnish 版本 4 开始,Inline-C 默认被禁用,所以除非你启用它,否则你不必担心它。

上述参数可以限制 VMOD 的加载仅从指定目录加载,从而将 VCL 管理员限制为预先批准的 VMOD 子集。

如果您这样做,我们相信您的本地系统不会受到 VCL 代码的损害。

2.1.4 HTTP 请求

我们已经竭尽全力使 Varnish 能够抵抗通过接收 HTTP 请求的套接字传入的任何内容,并且一般来说,您应该不需要进一步保护它。

需要注意的是,由于 VCL 是一种编程语言,它可以让您准确决定如何处理 HTTP 请求,因此您也可以决定用它们做愚蠢且有潜在危险的事情,包括让自己面临各种攻击和颠覆活动。

如果您有“管理”HTTP 请求,例如 PURGE 请求,我们强烈建议您使用 VCL 的访问控制列表 (ACL)将它们限制为受信任的 IP 号码/网络。

2.2 必需的命令行参数

启动 Varnish 时必须设置两个命令行参数,它们是:

  • 从哪个 TCP 端口提供 HTTP 服务,以及

  • 可以联系后端服务器的地方。

如果您通过使用提供的操作系统绑定包安装了 Varnish,您将在此处找到启动选项:

  • Debian, Ubuntu: /etc/default/varnish

  • Red Hat, Centos: /etc/sysconfig/varnish

  • FreeBSD: /etc/rc.conf (See also: /usr/local/etc/rc.d/varnishd)

2.2.1 '-a’监听地址

‘-a’ 参数定义了 Varnish 应该监听的地址,并为来自的 HTTP 请求提供服务。

您很可能希望将其设置为“:80”,这是 HTTP 的众所周知的端口。

你可以指定用逗号分隔的多个地址,如果你愿意,你可以使用数字或主机/服务名称,Varnish将尝试打开并服务尽可能多的地址,但如果没有一个可以打开,varnishd将不会开始。

这里有些例子:

-a :80
-a localhost:80
-a 192.168.1.100:8080
-a '[fe80::1]:80'
-a '0.0.0.0:8080,[::]:8081'

如果您的网络服务器在同一台计算机上运行,​​则必须先将其移至另一个端口号。

2.2.2 ‘-f’ VCL 文件或 '-b’后端

Varnish 需要知道在哪里可以找到它正在缓存的 HTTP 服务器。您可以使用“-b”参数指定它,也可以将其放入您自己的 VCL 文件中,并使用“-f”参数指定。

使用“-b”是一种快速入门方法:

-b localhost:81
-b thatotherserver.example.com:80
-b 192.168.1.2:80

请注意,如果指定名称,它最多可以解析为一个 IPv4 一个 IPv6 地址。

对于更高级的使用,您将需要使用 指定 VCL 程序-f,但您可以从以下内容开始:

backend default {
	.host = "localhost:81";
}

顺便说一句,这正是*“* -b”的作用。

2.2.3 可选参数

有关命令行参数的完整列表,请参阅 varnishd(1) options

2.3 CLI - 掌控 Varnish

一旦varnishd启动,您可以使用varnishadm 程序和命令行界面来控制它:

varnishadm help

如果您想varnishadm从远程系统运行,我们建议您在运行的ssh系统中使用varnishd。(但另请参阅: 本地和远程 CLI 连接)您可以通过 SSH 连接到varnishd计算机并运行varnishadm

ssh $hostname varnishadm help

如果您没有给出命令参数,varnishadm则以交互模式运行,并具有命令完成、命令历史记录和其他功能:

critter phk> ./varnishadm
200
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
FreeBSD,13.0-CURRENT,amd64,-jnone,-sdefault,-sdefault,-hcritbit
varnish-trunk revision 2bd5d2adfc407216ebaa653fae882d3c8d47f5e1

Type 'help' for command list.
Type 'quit' to close CLI session.
Type 'start' to launch worker process.

varnish>

CLI 总是返回一个三位数的状态代码来说明事情的进展情况。

200 和 201 表示OK,其他任何值都表示某种故障阻止了命令的执行。

(如果得到 201,则意味着输出被截断,请参阅cli_limit参数。)

当命令作为 的参数给出时varnishadm,不同于 200 或 201 的状态将导致它以状态 1 退出并在标准错误上打印状态代码。

2.3.1 您可以使用 CLI 做什么

从 CLI 您可以:

  • 加载/使用/丢弃VCL程序

  • 禁止(无效)缓存内容

  • 改变参数

  • 启动/停止工作进程

我们将在下面简要讨论其中的每一个。

加载、使用和丢弃 VCL 程序

所有缓存和策略决策均由 VCL 程序做出。

您可以加载多个 VCL 程序,但其中一个被指定为“活动”VCL 程序,这是所有新请求开始的地方。

加载新的VCL程序:

varnish> vcl.load some_name some_filename

加载将从文件中读取VCL程序,并编译它。如果编译失败,您将收到错误消息:

.../mask is not numeric.
('input' Line 4 Pos 17)
                "192.168.2.0/24x",
----------------#################-

Running VCC-compiler failed, exit 1
VCL compilation failed

如果编译成功,则加载 VCL 程序,现在您可以随时将其设为活动 VCL:

varnish> vcl.use some_name

如果您发现这是一个非常糟糕的主意,您可以再次切换回以前的 VCL 程序:

varnish> vcl.use old_name

切换是瞬时的,所有新请求将立即开始使用您激活的 VCL。当前正在处理的请求是使用它们开始时使用的任何 VCL 完成的。

我们强烈建议您设计一个紧急 VCL,并始终保持其加载,以便可以通过以下命令激活它:

vcl.use emergency

禁止缓存内容

Varnish 提供“清除”功能以从缓存中删除内容,但这需要您确切地知道它们是什么。

有时,能够将某些内容从缓存中删除而无需提供要删除的内容的确切列表,这很有用。

想象一下,例如,公司徽标发生了变化,现在您需要 Varnish 来停止从缓存中提供旧徽标:

varnish> ban req.url ~ "logo.*[.]png"

应该这样做,是的,这是一个正则表达式。

我们称之为“禁止”,因为对象仍在缓存中,但它们现在被禁止传递,而缓存的所有其余部分不受影响。

即使您想丢弃所有缓存的内容,禁止也比重新启动更快且破坏性更小:

varnish> ban obj.http.date ~ .*

备注:条件符号(==, !=, ~ 、 !~)

更改参数

可以使用“-p”参数在命令行上设置参数,但几乎所有参数都可以从 CLI 即时检查和更改:

varnish> param.show prefer_ipv6
200
prefer_ipv6         off [bool]
                    Default is off
                    Prefer IPv6 address when connecting to backends
                    which have both IPv4 and IPv6 addresses.

varnish> param.set prefer_ipv6 true
200

一般来说,修改参数不是一个好主意,除非有充分的理由,例如性能调整或安全配置。

大多数参数会立即生效,或者短暂延迟后生效,但其中一些参数需要您重新启动子进程才能生效。这在参数的描述中总是提到。

启动和停止工作进程

一般来说,您应该让工作进程保持运行,但如果您需要停止和/或启动它,明显的命令可以工作:

varnish> stop

和:

varnish> start

如果您varnishd从“-d”(调试)参数开始,则始终需要显式启动子进程。

如果子进程死亡,主进程将自动重新启动它,但您可以使用 auto_restart参数禁用它。

2.4 存储后端

2.4.1 简介

Varnish 具有可插拔存储后端。它可以将数据存储在具有不同性能特征的各种后端中。默认配置是使用大小有限的 malloc 后端。对于严格的 Varnish 部署,您可能需要调整存储设置。

2.4.2 default

语法:default[,size]

默认存储后端是 umem(如果可用)的别名,否则是 malloc。

2.4.3 malloc

语法:malloc[,size]

Malloc 是一个基于内存的后端。每个对象都将从内存中分配。如果您的系统内存不足,则会使用交换区。

请注意,大小限制仅限制实际存储,每个对象用于各种内部结构的大约 1k 内存也包含在实际存储中。

size 参数指定varnishd将分配的最大内存量 。假定大小以字节为单位,除非后跟以下后缀之一:

K, k 大小以千字节表示。M, m 大小以兆字节表示。G, g 大小以吉字节表示。T, t 大小以太字节表示。

默认大小是无限的。

malloc 的性能与内存速度有关,因此速度非常快。如果数据集大于可用内存,性能将取决于操作系统有效分页的能力。

2.4.4 umem

语法:umem[,size]

Umem 是比可以使用libumem的 malloc 后端更好的替代方案。所有其他配置方面都被视为与 malloc 相同。

libumem实现了一个与几乎所有现代操作系统中使用的内核内存分配器类似的平板分配器,并且被认为比经典实现更高效且可扩展。特别是,libumem包含在 OpenSolaris 后代操作系统系列中,其中 jemalloc(3) 不常见。

如果不使用libumem ,Varnish 将仅将其用于存储分配,并保留默认的 libc 分配器用于所有其他 Varnish 内存分配目的。

如果Varnish 初始化时libumem已经加载,则会输出以下消息:

notice: libumem was already found to be loaded
        and will likely be used for all allocations

表明libumem不仅仅用于存储。出现这种情况的可能原因有:

  • 某些库varnishd被链接到 被链接到 libumem(最有可能的libpcre2-8是,检查ldd

  • LD_PRELOAD_64=/usr/lib/amd64/libumem.so.1LD_PRELOAD_32=/usr/lib/libumem.so.1或者 LD_PRELOAD=/usr/lib/libumem.so.1设置

Varnish 还将输出此消息来推荐对所有分配使用 libumem 的设置:

it is recommended to set UMEM_OPTIONS=perthread_cache=0,backend=mmap
before starting varnish

应遵循此建议以获得 Varnish 的最佳libumem配置。需要在启动 Varnish 之前设置此环境变量,因为libumem一旦加载就无法重新配置。

2.4.5 文件

语法:文件,路径[,size[,granularity[,advice]]]

文件后端使用mmap将对象存储在由磁盘上未链接文件支持的虚拟内存中,依赖内核在访问文件的一部分时处理分页。

这意味着除了 Varnish 所需的任何内存之外,还需要有足够的*虚拟内存来容纳文件大小。*传统上,虚拟内存限制是用 来配置的 ,但现代操作系统对此限制有其他抽象,例如控制组 (Linux) 或资源控制 (Solaris)。ulimit -v

‘path’ 参数指定备份文件的路径或varnishd将在其中创建备份文件的目录的路径。

size 参数指定备份文件的大小。假定大小以字节为单位,除非后跟以下后缀之一:

K, k 大小以千字节表示。M, m 大小以兆字节表示。G, g 大小以吉字节表示。T, t 大小以太字节表示。

如果“path”指向现有文件并且未指定大小,则将使用现有文件的大小。如果“路径”不指向现有文件,则不指定大小是错误的。

如果备份文件已存在,它将被截断或扩展至指定大小。

请注意,如果varnishd必须创建或扩展文件,它不会预先分配添加的空间,从而导致碎片,这可能会对旋转硬盘驱动器的性能产生不利影响。使用dd(1)预先创建存储文件会将碎片减少到最低限度。

“粒度”参数指定分配的粒度。所有分配均向上舍入至此大小。假定粒度以字节为单位表示,除非后面跟有针对大小描述的后缀之一。

默认粒度是 VM 页面大小。如果您有许多小物体,则应减小尺寸。

文件性能通常受限于设备的写入速度,并且根据使用情况,还受限于寻道时间。

‘advice’ 参数告诉内核varnishd希望如何使用这个映射区域,以便内核可以选择适当的预读和缓存技术。可能的值为normalrandomsequential,分别对应于 MADV_NORMAL、MADV_RANDOM 和 MADV_SEQUENTIAL madvise() 建议参数。默认为 random.

在 Linux 上,大型对象和旋转磁盘应该受益于“顺序”。

2.4.6 已弃用的_持久性

语法:deprecated_persistent、路径、大小{实验性}

使用前,请阅读 持久消息

持久存储。Varnish 将以某种方式将对象存储在文件中,以便在计划或计划外关闭 Varnish 时确保大多数对象的生存。

“path”参数指定支持文件的路径。如果该文件不存在,Varnish 将创建它。

“size”参数指定备份文件的大小。大小以字节为单位表示,除非后跟以下后缀之一:

K, k 大小以千字节表示。M, m 大小以兆字节表示。G, g 大小以吉字节表示。T, t 大小以太字节表示。

Varnish 会将文件分割成逻辑筒仓,并以循环缓冲区的方式写入筒仓。在任何给定时间点,只有一个筒仓保持开放状态。整个筒仓被密封。当 Varnish 在关闭后启动时,它将丢弃任何未密封的筒仓中的内容。

请注意,使持久孤岛离线并同时使用禁令可能会导致问题。这是因为在筒仓离线时添加的禁令在筒仓重新进入缓存时不会应用到筒仓。从而使之前被禁止的物体重新出现。

2.5 临时存储

如果您将任何存储后端命名为“Transient”,它将用于瞬态(短暂的)对象。这包括返回合成对象时创建的临时对象。默认情况下,Varnish 将为此使用无限的 malloc 后端。

如果 TTL 低于参数“shortlived”,Varnish 会认为对象是短暂的。

2.6 调整缓存大小

决定缓存大小可能是一项棘手的任务。有几点需要考虑:

  • 您的热门数据集有多大。对于门户网站或新闻网站,这将是首页及其上所有内容的大小,以及从首页链接的所有页面和对象的大小。

  • 生成一个对象的成本有多高?有时,如果从后端提供图像的成本较低并且内存量有限,则仅缓存图像一段时间或根本不缓存它们是有意义的。

  • 使用varnishstat或其他工具观察n_lru_nuked计数器。如果您有大量 LRU 活动,那么您的缓存由于空间限制而正在逐出对象,您应该考虑增加缓存的大小。

请注意,存储的每个对象也会带来保留在实际存储区域之外的开销。因此,即使您指定Varnish,实际上也可能使用双倍的值。Varnish 每个对象的开销约为 1KB。因此,如果缓存中有大量小对象,开销可能会很大。-s malloc,16G

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值