我已经安装了 varnish 和 nginx,并使用 lets encrypt SSL 保护了我的网站。我针对 nginx cgi 缓存测试了 varnish,发现 varnish 在我的用例(wordpress)中速度更快一些。所以我需要一些帮助,关于如何使用 nginx 和 varnish 进行 SSL 终止以及如何将 http 转发到 https,因为我的网站仅支持 https。我正在运行 ubuntu 18.04,请帮帮我!!
它在 nginx 中给出了我的错误(端口 80 已被使用)
请帮我!
答案1
假设
- Nginx 有一个运行在端口 443处理传入的 HTTPS 请求
- Nginx 有一个运行在端口 80处理传入的 HTTP 请求并将其重定向到 Varnish
- Varnish 正在运行端口 6081位于 HTTPS Nginx 虚拟主机后面
- Nginx 可能还会在以下位置运行 vhost:端口 8080它不执行代理,而是充当实际的网络服务器,提供文件或 PHP 请求。
如你所见,我的设置与https://www.linode.com/docs/websites/varnish/use-varnish-and-nginx-to-serve-wordpress-over-ssl-and-http-on-debian-8/。这是因为我已经使用单独的 Nginx vhost 解决了 HTTP 到 HTTPS 重定向问题。
在这种情况下,Varnish 不是监听端口 80,而是监听端口 6081。
HTTPS 虚拟主机
以下是 Nginx 的示例虚拟主机处理 HTTPS 连接:
server {
listen 443 ssl;
keepalive_timeout 70;
server_name example.com www.example.com;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_certificate ssl.crt;
ssl_certificate_key ssl.key;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 4h;
access_log /var/log/nginx/example.com-access.log;
error_log /var/log/nginx/example.com-error.log;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:6081;
proxy_http_version 1.1;
}
}
HTTP 到 HTTPS 重定向虚拟主机
以下是将 HTTP 重定向到 HTTPS 的代码片段:
server {
server_name example.com www.example.com;
listen 80;
rewrite "^/$" https://example.com permanent;
rewrite "^/(.+)$" http://example.com/$1 permanent;
}
删节内容
虚拟主机已被编辑并包含示例值。请在server_name
表达式中相应地替换主机名。
还请确保ssl_certificate
和ssl_certificate_key
语句指向实际存在的文件。
答案2
试试这个。这些是我从运行 Nginx、Varnish 和 PHP-fpm 的 Ubuntu LEMP Digital Ocean Droplet 中获取的配置。它还具有重定向功能,可将所有流量转发到 https://wwww
这些文件是:
- 默认.vcl
- nginx.conf
- varnish_daemon
- varnish.service
默认.vcl
vcl 4.1;
import std;
backend projectname {
.host = "127.0.0.1";
.port = "8080";
.max_connections = 100;
.connect_timeout = 5s;
.first_byte_timeout = 90s;
.between_bytes_timeout = 2s;
}
acl purge {
"localhost";
"127.0.0.1";
"::1";
}
sub vcl_recv {
if (req.url ~ "^/\.well-known/acme-challenge/") {
set req.backend_hint = projectname;
return(pipe);
}
# Forward client's IP to the backend
if (req.restarts == 0) {
if (req.http.X-Real-IP) {
set req.http.X-Forwarded-For = req.http.X-Real-IP;
} else if (req.http.X-Forwarded-For) {
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
unset req.http.proxy;
set req.url = std.querysort(req.url);
set req.url = regsub(req.url, "\?$", "");
set req.http.Surrogate-Capability = "key=ESI/1.0";
if (std.healthy(req.backend_hint)) {
set req.grace = 10s;
}
if (!req.http.X-Forwarded-Proto) {
if(std.port(server.ip) == 443) {
set req.http.X-Forwarded-Proto = "https";
} else {
set req.http.X-Forwarded-Proto = "https";
}
}
# === STATIC FILES ===
# Properly handle different encoding types
if (req.http.Accept-Encoding) {
if (req.url ~ "\.(jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf)$") {
# No point in compressing these
unset req.http.Accept-Encoding;
} elseif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elseif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
# unknown algorithm (aka crappy browser)
unset req.http.Accept-Encoding;
}
}
if (req.http.Upgrade ~ "(?i)websocket") {
return (pipe);
}
if (req.url ~ "(\?|&)(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=") {
set req.url = regsuball(req.url, "&(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_\-\.%25]+)", "");
set req.url = regsuball(req.url, "\?(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_\-\.%25]+)", "?");
set req.url = regsub(req.url, "\?&", "?");
set req.url = regsub(req.url, "\?$", "");
}
if (req.method == "PURGE") {
if (!client.ip ~ purge) {
return (synth(405, client.ip + " is not allowed to send PURGE requests."));
}
return (purge);
}
if (req.method != "GET" &&
req.method != "HEAD" &&
req.method != "PUT" &&
req.method != "POST" &&
req.method != "TRACE" &&
req.method != "OPTIONS" &&
req.method != "PATCH" &&
req.method != "DELETE") {
return (pipe);
}
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
if (req.url ~ "^[^?]*\.(7z|avi|bmp|bz2|css|csv|doc|docx|eot|flac|flv|gif|gz|ico|jpeg|jpg|js|less|mka|mkv|mov|mp3|mp4|mpeg|mpg|odt|ogg|ogm|opus|otf|pdf|png|ppt|pptx|rar|rtf|svg|svgz|swf|tar|tbz|tgz|ttf|txt|txz|wav|webm|webp|woff|woff2|xls|xlsx|xml|xz|zip)(\?.*)?$") {
unset req.http.Cookie;
return(hash);
}
set req.http.Cookie = regsuball(req.http.Cookie, "(__utm|_ga|_opt)[a-z_]*=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "(__)?hs[a-z_\-]+=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "hubspotutk=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "_hj[a-zA-Z]+=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "(NID|DSID|__gads|GED_PLAYLIST_ACTIVITY|ACLK_DATA|ANID|AID|IDE|TAID|_gcl_[a-z]*|FLC|RUL|PAIDCONTENT|1P_JAR|Conversion|VISITOR_INFO1[a-z_]*)=[^;]+(; )?", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^;\s*", "");
if (req.http.cookie ~ "^\s*$") {
unset req.http.cookie;
}
}
sub vcl_pipe {
if (req.backend_hint == projectname) {
set req.http.Connection = "close";
return(pipe);
}
}
sub vcl_hash {
hash_data(req.http.X-Forwarded-Proto);
}
sub vcl_backend_response {
if (bereq.url ~ "^[^?]*\.(7z|avi|bmp|bz2|css|csv|doc|docx|eot|flac|flv|gif|gz|ico|jpeg|jpg|js|less|mka|mkv|mov|mp3|mp4|mpeg|mpg|odt|ogg|ogm|opus|otf|pdf|png|ppt|pptx|rar|rtf|svg|svgz|swf|tar|tbz|tgz|ttf|txt|txz|wav|webm|webp|woff|woff2|xls|xlsx|xml|xz|zip)(\?.*)?$") {
unset beresp.http.Set-Cookie;
set beresp.ttl = 1d;
}
if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
unset beresp.http.Surrogate-Control;
set beresp.do_esi = true;
}
# Unset the "pragma" header (suggested)
unset beresp.http.Pragma;
# Unset the "vary" header (suggested)
unset beresp.http.Vary;
set beresp.ttl = 10s;
set beresp.grace = 2h;
}
nginx.conf
user www-data;
worker_processes auto;
worker_rlimit_nofile 38000;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
http {
sendfile on;
autoindex off;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
reset_timedout_connection on;
keepalive_requests 100000;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_bucket_size 64;
charset UTF-8;
# Cloudflare IP's
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/12;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;
real_ip_header X-Forwarded-For;
client_max_body_size 128m;
client_body_buffer_size 2m;
client_header_buffer_size 64k;
large_client_header_buffers 16 128k;
fastcgi_buffers 4 32k;
fastcgi_buffer_size 32k;
fastcgi_busy_buffers_size 32k;
fastcgi_connect_timeout 60s;
fastcgi_next_upstream_timeout 40s;
fastcgi_next_upstream_tries 10;
fastcgi_read_timeout 60s;
fastcgi_send_timeout 60s;
fastcgi_cache_lock_timeout 60s;
open_file_cache max=35000 inactive=30s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_disable "msie6";
gzip_min_length 10240;
#gzip_min_length 1000;
gzip_buffers 4 16k;
gzip_comp_level 6;
gzip_types text/css text/js text/xml text/plain text/javascript
text/html
text/x-component
application/json
application/xml
application/x-javascript
application/javascript
application/vnd.ms-fontobject
application/rss+xml
font/truetype
font/opentype
image/svg+xml;
map_hash_max_size 4200;
map_hash_bucket_size 4200;
log_format main
'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
map $http_user_agent $is_non_search_bot {
default '';
~*(google|bing|pingdom|monitis.com|Zend_Http_Clienti) '';
~*(http|crawler|spider|bot|search|ForusP|Wget/|Python-urllib|PHPCrawl|bGenius) 'bot';
}
map $status $write_log {
444 0;
default 1;
}
map $http_user_agent $is_bad_client {
default 0;
~*(Sogou) 1;
~*(360Spider) 1;
~*(aiHitBot|AhrefsBot) 1;
~*(betaBot|BlackWidow|Bolt|BLEXBot|BUbiNG) 1;
~*(CazoodleBot|CPython|CCBot|ChinaClaw|Curious|CRAZYWEBCRAWLER|Custo) 1;
~*(Default|DIIbot|DISCo|discobot) 1;
~*(Exabot|eCatch|ecxi|EirGrabber|EmailCollector|EmailSiphon|EmailWolf|ExtractorPro|EyeNetIE) 1;
~*(FlashGet|Findxbot) 1;
~*(GetRight|GetWeb!|Go!Zilla|Go-Ahead-Got-It|Go.*package.*|GrabNet|Grafula|GT::WWW|GuzzleHttp) 1;
~*(heritrix|HaosouSpider|HMView|HTTP::Lite|HTTrack) 1;
~*(ia_archiver|IDBot|id-search|id-search.org|InterGET|InternetSeer.com|IRLbot) 1;
~*(JetCar) 1;
~*(larbin|LeechFTP|Lightspeedsystems|litemage_walker|LinksManager.com_bot|Lipperhey|linkwalker|LinkpadBot|lwp-trivial|ltx71) 1;
~*(Maxthon$|Mail.RU_Bot|MegaIndex.ru|meanpathbot|MFC_Tear_Sample|microsoft.url|Microsoft-IIS|Mozilla.*Indy|Mozilla.*NEWT|MJ12bot|MSFrontPage) 1;
~*(Navroad|NearSite|NetAnts|NetLyzer.*FastProbe|NetSpider|NetZIP|Nutch) 1;
~*(Octopus) 1;
~*(PageGrabber|panscient.com|pavuk|PECL::HTTP|PeoplePal|pcBrowser|Pi-Monster|PHPCrawl|PleaseCrawl|psbot|prijsbest|python-requests) 1;
~*(Qwantify) 1;
~*(RealDownload|ReGet|RedesScrapy|Rippers|RocketCrawler) 1;
~*(SBIder|Scrapy|Screaming|ScreenerBot|SEOprofiler|SeaMonkey$|SeznamBot|SemrushBot|sitecheck.internetseer.com|SiteSnagger) 1;
~*(SmartDownload|Snoopy|SputnikBot|Steeler|SuperBot|SuperHTTP|Surfbot|sqlmap) 1;
~*(tAkeOut|Teleport|Toata|TwengaBot|Typhoeus) 1;
~*(URI::Fetch|User-Agent|UserAgent) 1;
~*(voltron|Vagabondo|VoidEYE|Visbot) 1;
~*(webalta|WebAuto|[Ww]eb[Bb]andit|WebCollage|WebCopier|WebFetch|WebLeacher|WebReaper|WebSauger|WebStripper|WebWhacker|WhatsApp) 1;
~*(WebZIP|Wget|Widow|Wotbox|WWW-Mechanize|WWWOFFLE) 1;
~*(zermelo|Zeus|Zeus.*Webster|ZyBorg) 1;
}
map $uri $redirected_url {
default "none";
}
limit_req_zone $binary_remote_addr zone=one:10m rate=30r/s;
limit_req_zone $is_non_search_bot zone=bots:10m rate=22r/s;
limit_req_log_level error;
index index.php index.html;
upstream fastcgi_backend {
server unix:/var/run/php/php5.6-fpm.sock;
}
proxy_cache_path /var/cache/varnish levels=1:2 keys_zone=my_cache:8m max_size=1g inactive=60m use_temp_path=off;
server {
# redirect http to https://wwww
listen 8080;
listen [::]:8080;
server_name example.com;
return 301 https://example.com$request_uri;
}
server {
listen 8080;
listen [::]:8080;
root /var/www/current/default_site;
server_name example.com;
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php5.6-fpm.sock;
}
}
server {
# redirect https:// to https://wwww
listen 443;
listen [::]:443;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
return 301 https://example.com$request_uri;
}
server {
listen [::]:443 ssl http2;
listen 443 ssl;
root /var/www/current/default_site;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
ssl_session_cache shared:SSL:10m;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
add_header "X-XSS-Protection" "1; mode=block";
if ($request_uri ~* "^(.*/)index\.php(/?)(.*)" ) {
return 301 $1$3;
}
if ($is_bad_client) {
return 444;
}
location ~* \.(ico|jpg|jpeg|png|gif|svg)$ {
access_log off;
add_header Cache-Control "public";
add_header X-Frame-Options SAMEORIGIN always;
expires 365d;
}
location ~* \.(js|css|pdf)$ {
expires 365d;
access_log off;
add_header Cache-Control "public";
add_header X-Frame-Options SAMEORIGIN always;
add_header Access-Control-Allow-Origin "https://fast.fonts.net";
}
location ~* \.(html|swf)$ {
expires 30d;
add_header Cache-Control "public";
add_header X-Frame-Options SAMEORIGIN always;
}
location ~* \.(eot|ttf|otf|woff|woff2)$ {
access_log off;
add_header Cache-Control "public, no-transform";
add_header X-Frame-Options SAMEORIGIN always;
expires 365d;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location / {
proxy_cache my_cache;
proxy_cache_revalidate on;
proxy_cache_min_uses 3;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;
proxy_ignore_headers X-Accel-Expires;
proxy_ignore_headers Expires;
proxy_ignore_headers Cache-Control;
proxy_pass http://127.0.0.1:80;
# ALSO TRY YOUR SERVER IP proxy_pass http://99.100.101.102:80;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Host $host;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php5.6-fpm.sock;
}
}
}
varnish_daemon
这是来自“nano /etc/default/varnish”的代码
DAEMON_OPTS="-a :80 \
-T localhost:6082 \
-p feature=+http2 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-s malloc,1g"
varnish.service
这是来自“nano /lib/systemd/system/varnish.service”的代码
[Unit]
Description=Varnish HTTP accelerator
Documentation=https://www.varnish-cache.org/docs/6.1/ man:varnishd
[Service]
Type=simple
LimitNOFILE=131072
LimitMEMLOCK=82000
ExecStart=/usr/sbin/varnishd -j unix,user=vcache -F -a :80 -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -p feature=+http2 -s malloc,1G
ExecReload=/usr/share/varnish/varnishreload
ProtectSystem=full
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
[Install]
WantedBy=multi-user.target