Nginx 性能优化及反向代理 NextCloud

Nginx 是一个异步框架的网页服务器,具有占用内存少、稳定性高、可大量并行处理等特点。截止 2018 年,全球有 30.46% 的网站使用 Nginx 作为代理。除了网页代理外,Nginx 也可作为反向代理、负载均衡等应用,本站使用的网页服务器就是 Nginx。 我的 Nextcloud 私有云是搭建在 HostHatch 洛杉矶数据中心的大容量机械硬盘 VPS 上。由于性能有限加上 HostHatch 没有对中国路由进行特别优化,导致国内直连的情况下丢包严重,连接状态极差。于是我用狗云圣何塞机房 4837 线路的 VPS 作为 Nextcloud 的中转来解决访问速度的问题,同时把本站也搭建在狗云的VPS上就不会有访问困难的问题了。这两种需求利用 Nginx 都能很好的满足。 我 Nginx 配置的基本架构: Nginx 提供本站的网页服务,并处理本站和 Nextcloud 的 HTTPS 加密。 Nginx 为 Nextcloud 做反向代理,使客户端访问 Nextcloud 经过网络更好的 Nginx 所在的服务器来加速访问。 优化要点: 合理的配置本地缓存 开启压缩并做适当的配置 反向代理服务器不要缓存后端的数据,只作为一个桥梁来提供中转服务。这样数据传输更加直接,同时也能减轻反向代理服务器的压力。(我的反向代理服务器只有 5G 的硬盘,如果开启反向代理缓存的话,向后端传输数据的最大文件大小会受这个缓存的限制) HTTPS 加密方式的选择 我的nginx.conf配置 user site site; #用户和用户组 worker_processes auto; #CPU 核心数 worker_rlimit_nofile 8192; #最大打开文件数量 error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events { use epoll; #epoll事件模型 worker_connections 1024; #单个 worker 进程允许客户端最大连接数 multi_accept on; #worker 按串行方式来处理连接 } http { include /etc/nginx/mime.types; #媒体类型 default_type application/octet-stream; #媒体类型 charset UTF-8; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; # 安全 # add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; # add_header X-Robots-Tag none; # add_header X-Download-Options noopen; # add_header X-Permitted-Cross-Domain-Policies none; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # add_header X-Frame-Options SAMEORIGIN; #不允许页面从框架 frame 或 iframe 中显示 ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_session_tickets on; ssl_stapling on; ssl_stapling_verify on; sendfile on; #开启高效文件传输模式 tcp_nopush on; #防止网路阻塞 keepalive_timeout 65; #客户端连接保持会话超时时间 tcp_nodelay on; #防止网络阻塞 types_hash_max_size 2048; client_header_buffer_size 4096; #客户端请求头部的缓冲区大小,getconf PAGESIZE 命令查看 open_file_cache max=8192 inactive=20s; #打开文件指定缓存,建议和打开文件数一致,inactive 经过多长时间文件没被请求后删除缓存 open_file_cache_valid 30s; #多长时间检查一次缓存的有效信息 open_file_cache_min_uses 1; #open_file_cache 指令中的 inactive 时间内文件的最少使用次数,1次都没用,删除 client_header_timeout 15; #设置请求头的超时时间,超过这个时间没有发送任何数据,返回 request time out 错误 client_body_timeout 15; #设置请求体的超时时间 reset_timedout_connection on; #关闭不响应的 client 连接,释放那个 client 所占有的内存 send_timeout 15; #超过这个时间,客户端没有任何活动,nginx 关闭连接 server_tokens off; #关闭 Nginx 版本号 client_max_body_size 614400m; #上传文件大小限制 # 反向代理 proxy_buffering off; proxy_max_temp_file_size 614400m; #反向代理上传文件大小限制 proxy_set_header X-Real_IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_pass_header Set-Cookie; proxy_pass_header X-CSRF-TOKEN; proxy_set_header Upgrade $http_upgrade; #连接升级为 WebSocket proxy_set_header Connection $connection_upgrade; #连接 map proxy_connect_timeout 60s; #代理超时 proxy_read_timeout 60s; #读取超时 proxy_send_timeout 60s; #请求改善超时 #proxy_redirect off; fastcgi_connect_timeout 600; #指定连接到后端 FastCGI 的超时时间 fastcgi_send_timeout 600; #向 FastCGI 传送请求的超时时间 fastcgi_read_timeout 600; #指定接收 FastCGI 应答的超时时间 fastcgi_buffer_size 64k; #指定读取 FastCGI 应答第一部分需要用多大的缓冲区 fastcgi_buffers 4 64k; #指定本地需要用多少和多大的缓冲区来缓冲 FastCGI 的应答请求 fastcgi_busy_buffers_size 128k; #建议设置为 fastcgi_buffers 的两倍 fastcgi_temp_file_write_size 128k; #在写入 fastcgi_temp_path 时将用多大的数据块,默认值是 fastcgi_buffers 的两倍 fastcgi_temp_path /tmp; #缓存临时目录 fastcgi_intercept_errors on; #指定是否传递 4xx 和 5xx 错误信息到客户端 fastcgi_cache_path /tmp/blog levels=1:2 keys_zone=cache_fastcgi:300m inactive=60m max_size=3584m; #fastcgi_cache 缓存目录 fastcgi_cache cache_fastcgi; #开启 FastCGI 缓存并为其指定一个名称 fastcgi_cache_valid 200 302 1h; #用来指定应答代码的缓存时间 fastcgi_cache_valid 301 1d; #将 301 应答缓存一天 fastcgi_cache_valid any 1m; #将其他应答缓存为1分钟 fastcgi_cache_min_uses 1; #设置经过多少次请求的相同 URL 将被缓存 fastcgi_cache_key http://$host$request_uri; #设置 web 缓存的 Key 值 #fastcgi_pass; #指定 FastCGI 服务器监听端口与地址 gzip on; #开启压缩 gzip_disable "msie6"; gzip_min_length 1k; #允许压缩的页面最小字节数 gzip_buffers 32 4k; #压缩缓冲区大小 gzip_http_version 1.1; #压缩版本 gzip_comp_level 9; #压缩比例(1-9) gzip_proxied any; #对代理启用压缩 gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; gzip_vary on; #varyheader 支持 map $http_upgrade $connection_upgrade { default upgrade; '' close; } include /etc/nginx/conf.d/*.conf; } 我的 conf.d 里面本站服务器配置 server { listen 443 ssl; #listen [::]:443 ssl ipv6only=on; server_name sixdian.com; root /home/site/sixdian.com; ssl_certificate /etc/letsencrypt/live/sixdian.com-0001/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/sixdian.com-0001/privkey.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; # expires 缓存调优 location ~* \.(ico|jpeg|gif|png|bmp|swf|flv)$ { expires 30d; #log_not_found off; access_log off; } location ~* \.(js|css)$ { expires 1d; log_not_found off; access_log off; } # 防盗链(未成功) #location ~*^.+\.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)$ { #valid_referers sixdian.com; #if($invalid_referer) { #return 404; #break; #} #access_log off; #} } server { listen 80; #listen [::]:80 ipv6only=on; server_name sixdian.com; return 301 https://sixdian.com$request_uri; } server { listen 80; server_name www.sixdian.com; return 301 https://sixdian.com$request_uri; } 我 conf.d 里面 Nextcloud 服务器配置 server { listen 443 ssl; server_name drive.sixdian.com; ssl_certificate /etc/letsencrypt/live/sixdian.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/sixdian.com/privkey.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; location / { proxy_pass http://s1.sixdian.com:****; } location = /.well-known/carddav { return 301 $scheme://drive.sixdian.com/remote.php/dav/files/****/; } location = /.well-known/caldav { return 301 $scheme://drive.sixdian.com/remote.php/dav/files/****/; } } server { listen 80; server_name drive.sixdian.com; return 301 https://drive.sixdian.com$request_uri; location = /.well-known/carddav { return 301 $scheme://drive.sixdian.com/remote.php/dav/files/****/; } location = /.well-known/caldav { return 301 $scheme://drive.sixdian.com/remote.php/dav/files/****/; } } 我的 NextCloud 服务器 config.php 配置文件 位置在:/var/snap/nextcloud/current/nextcloud/config/config.php ...

April 29, 2022

Linux 系统的安全设置

Root 是 Linux 系统的超级管理员账户,拥有整个系统的最高权限,可操作系统内的所有对象。一般情况下开放了对外服务的linux系统需要设置一些安全策略来保证服务器的安全,同时亦能防止系统管理员由于平时管理过程中的误操作而导致系统不可挽回的错误。 SELinux 是 Linux 内核的安全模块,Root 账户的登录权限可由 SELinux 模块进行定义。 下面就介绍如何对系统进行设定来规避一些潜在的安全风险。 安全设置思路 禁用 root 登录权限 修改 ssh 默认端口 Root 用户的禁止登录设置 useradd username #username 为你要添加的用户名称 passwd username #设置 username 的用户密码 vi /etc/ssh/sshd_config #打开 ssh 配置文件 PermitRootLogin no #在 ssh 配置文件中找到 PermitRootLogin 这项,把后面默认的 yes 修改为 no 禁止 root 用户登录 service sshd restart #重启 sshd 服务 ssh 默认端口的修改 firewall-cmd --zone=public --add-port=xxxx/tcp --permanent #系统防火墙开放需要加入的端口,xxxx 为你需要加入的端口号 firewall-cmd --reload #重新加载系统防火墙设置,使刚才加入的端口生效 systemctl restart firewalld.service #重启系统防火墙 firewall-cmd --list-ports #列出系统防火墙已开放端口,你会发现你刚才设置的端口号已经加入其中 vi /etc/ssh/sshd_config #打开 ssh 配置文件 #Port 22 #默认 ssh 登录端口,前面加#号注释掉默认的22端口 Port xxxx #xxxx 为你需要添加 ssh 登录权限的端口号 semanage port -a -t ssh_port_t -p tcp xxxx #xxxx 为你需要添加 ssh 登录权限的端口号,这一步是将端口加入到 SELinux 安全模块 semanage port -l|grep ssh #列出具有 ssh 权限的端口号,出现你设置的端口号证明向 SELinux 已经加入成功 systemctl reload sshd #重新加载 ssh 服务使刚才的设置生效 systemctl restart sshd #重启 ssh 服务 reboot #重启 ssh username@ip:port #尝试用新的端口号登录系统

April 23, 2022

利用 Docker 容器安装 Haproxy

Docker 是一个开源软件平台。与虚拟机类似,准确的说是在操作系统层虚拟化,让软件成为标准化的单元。它可以使几乎任何软件部署到跨平台的操作系统上。 Haproxy 是用 C 语言编写的开源 TCP/HTTP 代理、负载均衡应用程序。 下面就介绍我在 Rocky Linux 平台下用 Docker 部署 Haproxy 实现代理后端网站的案例 设置存储库 sudo yum install -y yum-utils sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo 安装 Docker 引擎 sudo yum install docker-ce docker-ce-cli containerd.io 启动 Docker 并设置开机启动 sudo systemctl start docker sudo systemctl enable docker 拉取 Haproxy 容器镜像并启动容器 docker run -d --name haproxy -v /etc/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro -p 80:80 -p 443:443 -p 8500:8500 --restart always haproxy:2.3.19-alpine3.15

April 22, 2022

Hugo 使用 Jane 主题常用的一些配置

Hugo 下的 Jane 主题是基于 even 主题进行的重新改造,主要有以下特色: 响应式设计 多国语言支持 支持多个 Shortcode 单独设计的标签页和分类页 支持社交网站链接 优秀的分页、目录、注脚样式 使用更快的 Chroma 代码高亮 自定义 css、js、head 支持子目录 搜索引擎优化 初始化的样式展示的元素繁多可能不太符合每个人的实际需求,我们需要对需要显示的内容样式进行修改来增强站点整体的美感。下面就介绍如何改靠自己的独特主题: 默认情况下生成的站点部署后我我们会发现在手机上点按菜单位置无效,无法正常显示下拉菜单。我们可以按照下面的方法让菜单能在移动端正常显示。 Jane 主题移动端无法显示下拉菜单的解决方法 themes\jane\layouts\partials\scripts.html #根据路径找到这个文件,删除其中的 integrity 属性 <script type="text/javascript" src="{{ $secureJS.RelPermalink }}" integrity="{{ $secureJS.Data.Integrity }}" crossorigin="anonymous"></script> 另外现在人们通过 RSS 客户端阅读的方式已经越来越少,Jane 主题内的 RSS 订阅图标我个人觉得太过多余不符合我追求简洁的审美观,所以也要对它进行隐藏处理。具体处理方法如下: Jane 主题底部 RSS 订阅图标删除 ./layouts/partials/social_links.html #在 themes 文件夹下根据路径找到这个文件,删除以下代码 <!-- {{/* RSS icon */}} {{ with .Site.GetPage "home" -}} {{- with .OutputFormats.Get "RSS" -}} <a href="{{ .Permalink }}" rel="noopener {{ .Rel }}" type="{{ .MediaType.Type }}" class="iconfont" title="rss" target="_blank"> {{ partial "svg/rss.svg" }} </a> {{ end -}} {{- end -}} --> 其它需要设置的细节内容过多,而且过于简单,下面统一做个总结: ...

April 21, 2022

利用 Hugo 搭建 Blog

Hugo 是一个用 Go 语言编写的开源静态网站生成器,只需几秒钟即可生成一个网站,被认为是目前世界上最快的网站构建框架(本站的搭建就是基于 Hugo)。下面就介绍如何利用 Hugo 建立自己的独立 Blog。 本方案需具备以下条件: 一台拥有 80 端口权限的 Linux 服务器或 VPS。(本教程是基于 Rocky Linux 操作系统的 VPS) 拥有一个域名并解析到目标服务器IP。 大致步骤: 本地电脑利用 Hugo 生成静态网站。 利用 Git(一个开源分布式版本控制工具)将本地生成的网站部署到服务器。 服务器上使用 Nginx(一个异步框架的网页服务器)为网站提供代理服务。 使用 Let’s Encrypt 的 TSL 证书为网页传输提供加密特性。 安装 Git 本地下载安装 Git 并设置环境变量 安装 Hugo 本地下载安装 Hugo 利用 Hugo 创建一个新站点 终端下执行如下代码: hugo new site sitename #其中 sitename 为站点文件夹名。 这样就在当前目录下生成一个名叫 “sitename” 的初始站点文件夹。 进入站点目录: cd sitename 你会看到站点目录结构: - archetypes - content - data - layouts - public - resources - static - themes * config.toml 添加主题 cd themes git clone https://github.com/xianmin/hugo-theme-jane.git --depth=1 themes/jane 复制示例文件到站点内容目录: ...

April 20, 2022