个人博客进阶设置

阿里云 + Ubuntu 24.04 + Nginx + https + Hexo + Butterfly + local CDN

一、环境准备

1. 阿里云安全组端口配置

关闭4000端口 — hexo本地服务端口

开放443端口 — https

2. 申请域名

作者是在阿里云中租赁的域名

域名注册_域名查询_域名申请_域名购买_域名续费_国际域名-万网-阿里云品牌

3. 申请证书

作者是在阿里云中申请的证书
数字证书管理服务管理控制台

4. 下载证书

1
mkdir /etc/nginx/cear

在官网下载证书后放在/etc/nginx/cear路径下

5. 备案

网站备案_ICP备案_备案迁移_App备案_小程序备案_备案-阿里云

二、Nginx配置

1. 新建Nginx配置

1
touch /etc/nginx/sites-available/<domain_name>

2. 配置<domain_name>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##

# Default server configuration
#

# HTTP 服务器 - 只做重定向
server {
listen 80;
listen [::]:80;
server_name johnding.cn www.johnding.cn;

# 更高效的重定向方式
return 301 https://$server_name$request_uri;
}

server {
listen 443 ssl;
listen [::]:443 ssl;
server_name johnding.cn www.johnding.cn;

# SSL 证书配置
ssl_certificate /etc/nginx/cert/johnding.cn.pem;
ssl_certificate_key /etc/nginx/cert/johnding.cn.key;

# SSL 优化配置
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
ssl_ecdh_curve secp384r1;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

# 安全头配置
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "strict-origin-when-cross-origin";
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; img-src 'self' https: data:; style-src 'self' 'unsafe-inline' https:; font-src 'self' https: data:; frame-src 'self'; object-src 'none'";
add_header Permissions-Policy "geolocation=(), midi=(), camera=(), usb=(), magnetometer=(), accelerometer=(), gyroscope=(), payment=()";
add_header Cross-Origin-Embedder-Policy "credentialless";
add_header Cross-Origin-Opener-Policy "same-origin";
add_header Cross-Origin-Resource-Policy "cross-origin";

# 解决跨域问题
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';

# 静态文件根目录(必须正确设置)
root /home/ding/blog/public;

# 启用gzip压缩(核心优化)
gzip on;
gzip_types
text/css
application/javascript
image/svg+xml
application/json
font/woff2
text/plain;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_vary on;

location = /css/all.min.css {
# 长期缓存(1年)
# expires 1y;
# add_header Cache-Control "public, immutable, max-age=31536000, must-revalidate";
# 开发阶段 缓存1天
expires 1d;
add_header Cache-Control "public, immutable, max-age=86400, must-revalidate";

# 预加载关键JS(消除串行加载)
add_header Link "</js/main.js>; rel=preload; as=script";
add_header Link "</js/utils.js>; rel=preload; as=script";

# 优先尝试本地文件
try_files $uri @proxy;

# 禁用gzip压缩(小文件压缩反而更慢)
gzip off;
}

# 关键CSS文件 - 强制预加载+长期缓存
location = /css/index.css {
# 长期缓存(1年)
# expires 1y;
# add_header Cache-Control "public, immutable, max-age=31536000, must-revalidate";
# 开发阶段 缓存1天
expires 1d;
add_header Cache-Control "public, immutable, max-age=86400, must-revalidate";

# 预加载关键JS(消除串行加载)
add_header Link "</js/main.js>; rel=preload; as=script";
add_header Link "</js/utils.js>; rel=preload; as=script";

# 优先尝试本地文件
try_files $uri @proxy;

# 禁用gzip压缩(小文件压缩反而更慢)
gzip off;
}

# 关键JS文件 - 长期缓存
location = /js/main.js {
# 长期缓存(1年)
# add_header Cache-Control "public, immutable, max-age=31536000, must-revalidate";
# expires 1y;
# 开发阶段 缓存1天
expires 1d;
add_header Cache-Control "public, immutable, max-age=86400, must-revalidate";

try_files $uri @proxy;
}

location = /js/utils.js {
# 长期缓存(1年)
# expires 1y;
# add_header Cache-Control "public, immutable, max-age=31536000, must-revalidate";
# 开发阶段 缓存1天
expires 1d;
add_header Cache-Control "public, immutable, max-age=86400, must-revalidate";

try_files $uri @proxy;
}

# 通用静态资源规则
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|webp|woff2)$ {
try_files $uri @proxy;
# expires 30d;
# add_header Cache-Control "public, immutable, max-age=2592000";
# 开发阶段 缓存1天
expires 1d;
add_header Cache-Control "public, immutable, max-age=86400, must-revalidate";
}

# 特别针对不蒜子的配置
location ~* busuanzi {
proxy_pass http://localhost:4000;
add_header Cross-Origin-Resource-Policy "cross-origin";
add_header Access-Control-Allow-Origin *;
proxy_hide_header 'access-control-allow-origin';
}

# 代理服务配置
location @proxy {
proxy_pass http://localhost:4000;
proxy_set_header Host $host;
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 $scheme;

# 保持长连接
proxy_http_version 1.1;
proxy_set_header Connection "";
}

# 动态内容(禁用缓存)
location / {
try_files $uri @proxy;
expires -1;
add_header Cache-Control "no-cache";
}
}

3. 创建符号链接

1
ln -s /etc/nginx/sites-available/<domain_name> /etc/nginx/sites-enabled/<domain_name>

4. 检查配置

1
nginx -t

5. 重启nginx服务

1
systemctl restart nginx

三、_config.yml配置

1. 修改url地址

1
url: https://<域名>

2. 重启服务

1
2
cd /home/ding/blog
pm2 restart run.js

3. 测试链接

在浏览器中输入域名访问

四、使用本地CDN

1. 安装hexo-butterfly-extjs

1
npm install hexo-butterfly-extjs --save

2. 修改_config.butterfly.yml配置

1
2
3
4
5
6
7
CDN:
# 内部和第三方脚本的 CDN 提供商
# 两者的选项:local/jsdelivr/unpkg/cdnjs/custom
# 注意: Dev 版本只能使用 'local' 作为内部脚本
# 注意:将第三方脚本设置为 'local' 时,需要安装 hexo-butterfly-extjs
internal_provider: local
third_party_provider: local <-- 修改点

3. 重启hexo服务

1
pm2 restart run.js

五、公安联网备案

全国互联网安全管理平台

如何填写公安联网备案公安联网备案信息指南_备案(Filing Service)-阿里云帮助中心

六、效果演示

John Ding - study notes

七、参考资料

  1. 网站备案_ICP备案_备案迁移_App备案_小程序备案_备案-阿里云
  2. 如何填写公安联网备案公安联网备案信息指南_备案(Filing Service)-阿里云帮助中心