Varnish 是一种 Web 应用程序加速器,有助于加快网站速度。它的工作原理是坐在 Web 服务器前面并缓存由它提供服务的网页。
当发出对网页的请求时,Varnish 将此请求传递给 Web 服务器,然后该服务器像往常一样响应该请求。Varnish 然后缓存这个请求的结果,然后将它发送给用户。这意味着下次请求页面时,页面的缓存版本将发送给用户,而 Web 服务器实际上并不是该过程的一部分。由于 Varnish 不运行任何网站代码或访问任何数据库,因此响应比来自 Web 服务器的原始响应快得多。事实上,简单地使用 Varnish 就可以在没有太多配置的情况下大幅提高网站速度。Varnish 非常擅长这项工作,可以显着加快网站速度。
Varnish 不能满足的一件事是 HTTPS 流量。这是设计使然,因此如果您有 Varnish 设置,如果您想使用加密的 HTTPS 流量,则需要完全绕过它。
解决此问题的一种方法是使用称为 Pound 的反向代理系统。Pound 位于 HTTPS 端口上的 Varnish 前面,并在将它们发送到 Varnish 之前解密所有 HTTPS 请求。所有正常的 HTTP 流量都被 Pound 忽略并通过 Varnish 并按正常方式处理。
我不打算在这里安装和设置 Varnish,因为这本身就是一个冗长的操作。如果您有兴趣,那么我已经写了安装和配置 Varnish 的过程的描述,其中还包括配置 Drupal 的描述。
要在基于 Debian 的系统上安装 Pound,只需运行以下命令。
sudo apt-get install pound
基于 RedHat 的系统非常相似,但在这种情况下它们使用 yum。
sudo yum install pound
开箱即用,Pound 不会在系统启动时启动,要设置此编辑文件 /etc/default/pound.conf 中的设置。
startup=1
在编辑主要的 Pound 配置之前,我们需要生成一个 Pound 理解的证书文件,以便它可以解密我们的 HTTPS 传输并将它们转发到 Varnish。如果您已经拥有受信任的 SSL 证书,您可能仍需要完成此步骤才能生成 Pound 满意的证书。出于测试目的,我们将使用 Ubuntu 附带的现有测试 SSL 证书来演示如何执行此操作(保存在 /etc/ssl/certs/ssl-cert-snakeoil.pem)。要为 Pound 生成证书文件,您需要像这样将 pem 和密钥文件组合在一起。
mkdir keys cp /etc/ssl/certs/ssl-cert-snakeoil.pem keys sudo openssl rsa -in /etc/ssl/private/ssl-cert-snakeoil.key >> keys/ssl-cert-snakeoil.pem
主要的 Pound 配置文件位于 /etc/pound/pound.cfg,需要对其进行编辑以做两件事。默认情况下,Pound 将侦听端口 80,我们的 Varnish 服务器已经在侦听该端口,因此需要将其删除。然后我们需要添加一个规则,让 Pound 监听 HTTPS 流量并告诉它如何处理请求。
您的 Pound 配置文件应如下所示。
User "www-data" Group "www-data" RootJail "/var/pound" LogLevel 1 ## check backend every X secs: Alive 30 # poundctl control socket Control "/var/run/pound/poundctl.socket" ListenHTTPS Address 10.0.0.1 # put your server's public IP address here Port 443 Cert "/path/to/ssl-cert-snakeoil.pem" HeadRemove "X-Forwarded-Proto" AddHeader "X-Forwarded-Proto: https" Service BackEnd Address 127.0.0.1 Port 80 End End End
上述选项设置了一些默认设置,然后允许 Pound 侦听传入的 HTTPS 请求。我们告诉 Pound 解密这些请求,然后将它们作为未加密的流量转发到端口 80。X-Forwarded-Proto 标头设置为“https”,以便 Varnish 和 Web 应用程序知道它应该处理 HTTPS 流量。'Cert' 参数引用我们上面生成的 pem 文件,但应更改为您的受信任证书。
另请注意,我们没有在此处添加“ListenHTTP”指令,因为我们根本不希望 Pound 监听 HTTP 流量。
如果您已经设置了您的网络服务器来侦听 HTTPS 流量,那么您需要在启动 Pound 之前将其关闭。在 Apache 中,这通常以 Listen 指令的形式保存。您可以删除它,也可以通过更改以下配置指令来更改端口。
<ifmodule mod_ssl.c=""> Listen 44300 </ifmodule>
最后,我们只需要在我们的default.vcl文件中添加一个 vcl_hash 回调。这将允许我们在尝试缓存页面时区分 HTTP 和 HTTPS 流量。
sub vcl_hash { hash_data(req.url); if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } # Use special internal SSL hash for https content # X-Forwarded-Proto is set to https by Pound if (req.http.X-Forwarded-Proto ~ "https") { hash_data(req.http.X-Forwarded-Proto); } return (hash); }
有了所有这些,您应该能够重新启动 Apache、Varnish 和 Pound 以使所有内容都在一起。
sudo service apache2 restart && sudo service varnish restart && sudo service pound restart
您可以通过运行“netstat -nlp”来仔细检查哪些服务正在侦听哪些端口,这应该会产生如下内容。这假设 Varnish 将流量发送到的后端端口是 8080,这是 Apache 响应的端口。
$ sudo netstat -nlp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name ..... tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 11605/varnishd tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 11554/apache2 ..... tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 11647/pound ......
如果您在启动 Pound 时遇到问题,请查看 Pound 日志,该日志将保存在 Debian 系统上的 /var/log/syslog 中。
sudo tail /var/log/syslog
在这里,它会告诉您任何端口冲突或不正确的 SSL 证书文件,因此您应该能够找出问题所在并进行更正。
此处需要牢记一两个安全注意事项。如果您正在解密流量,然后通过网络将此流量发送到不同的服务器,则该流量被拦截的可能性很小。出于这个原因,Pound 必须仅用于私有网络或与 Varnish 实例在同一台机器上。
最后,那些在家里跟随的人可能会意识到这里房间里的大象。尽管 HTTP 和 HTTPS 匿名流量都会被缓存,但不会缓存经过身份验证的流量。因此,如果您的所有用户都登录查看您的网站,那么使用 Pound 通过 Varnish 发送流量不会减少您需要的资源量。主要问题是您并不真的希望向已登录的用户提供缓存页面,因为他们有可能看到另一个用户生成的缓存。您可以做一些事情来允许缓存,包括设置自定义标头和 cookie,甚至 ESI(包括边缘端)。
作为奖励,我想我会创建一个 Ansible playbook,它将在 Ubuntu 设置上与现有的 Varnish 一起安装 Pound。本剧本中使用的两个模板( pound_config.j2 和 pound_initscript.j2 )可以在上面的文章中找到。
--- - hosts: all tasks: - name: install Pound apt: pkg=pound state=installed sudo: true - name: setup Pound initscript template: xx_src=pound_initscript.j2 dest=/etc/default/pound sudo: true - name: create snakeoil pem certificate directory file: path=/home/{{ user }}/keys state=directory - name: copy snakeoil certificate pem file command: cp /etc/ssl/certs/ssl-cert-snakeoil.pem /home/{{ user }}/keys creates=/home/{{ user }}/keys/ssl-cert-snakeoil.pem - name: generate pem file with key file shell: openssl rsa -in /etc/ssl/private/ssl-cert-snakeoil.key >> ssl-cert-snakeoil.pem chdir=/home/{{ user }}/keys creates=/home/{{ user }}/keys/ssl-cert-snakeoil-pound.pem sudo: true - name: add Pound config file template: xx_src=pound_config.j2 dest=/etc/pound/pound.cfg sudo: true notify: - restart pound - name: ensure pound is started service: name=pound state=started sudo: true - name: get iptables rules shell: iptables -L register: iptablesrules sudo: true always_run: true changed_when: False - name: add apache iptable rule command: iptables -I INPUT 1 -p tcp --dport 443 -j ACCEPT -m comment --comment "pound https port" sudo: true when: iptablesrules.stdout.find("pound") == -1 notify: - save iptables handlers: - name: restart pound service: name=pound state=restarted sudo: true - name: save iptables command: iptables-save sudo: true notify: - restart ufw - name: restart ufw service: name=ufw state=restarted sudo: true