├── README.md ├── images ├── steps.png └── steps.pptx ├── install-nginx.sh ├── nginx.conf ├── rrd_nginx.pl └── status_index.html /README.md: -------------------------------------------------------------------------------- 1 | ## [原创]step-by-step install Nginx反向代理服务器(Ubuntu 18.04 LTS) 2 | 3 | 本文原创: 4 | 5 | * **中国科学技术大学 张焕杰** 6 | * **厦门大学 郑海山** 7 | 8 | 修改时间:2018.06.13 9 | 10 | 对于仅仅支持IPv4的HTTP服务器,按下图所示步骤,通过增加Nginx反向代理服务器,可以分三步迁移为支持IPv4/v6 协议的HTTP、HTTPS、HTTP/2服务器。 11 | 12 | 步骤一--步骤十 描述了第一步的迁移过程。第二步迁移仅仅需要修改DNS服务器即可。 13 | 步骤十一 描述了第三步的迁移过程。 14 | 15 | Nginx反向代理服务器是高性能的HTTP/HTTPS/TCP代理软件,单台服务器很轻松支持10万+并发连接。[中国科学技术大学](https://www.ustc.edu.cn)负责处理600余个网站的Nginx服务器大部分时间并发连接2000左右,也就是说1台Nginx服务器完全可以满足一个学校的所有网站使用。 16 | 17 | Nginx在进行反向代理时,发给HTTP服务器的请求,增加了以下字段: 18 | 19 | * X-Real-IP: 客户端来源IP地址 20 | * X-Forwarded-Proto: 用户请求的协议,是http或https 21 | 22 | 特别注意:如果您的HTTP服务器前有WAF设备防护,增加Nginx服务器后,WAF设备看到的访问来源IP是Nginx服务器的IP地址,而不是真实的客户端IP地址。 23 | 一旦WAF设备认为有攻击嫌疑而封锁IP,会导致Nginx服务器无法访问HTTP服务器。因此需要调整WAF设备的配置,让WAF设备把HTTP请求中的X-Real-IP字段作为来源IP地址。 24 | 25 | ![ipv6 trans](images/steps.png) 26 | 27 | ## 一、Ubuntu 18.04 LTS安装 28 | 29 | 获取安装包 ISO,您可以从以下站点获取 `ubuntu-18.04-live-server-amd64.iso`,文件大小大约是806MB。 30 | 31 | * [中国科大镜像站](http://mirrors.ustc.edu.cn/ubuntu-releases/18.04/) 32 | * [上海交大镜像站](http://ftp.sjtu.edu.cn/ubuntu-cd/18.04/) 33 | * [163镜像站](http://mirrors.163.com/ubuntu-releases/18.04/) 34 | 35 | 说明:Ubuntu还有个更加灵活的安装程序,安装后占用空间更少,安装过程选择更多,熟练人士可以选择 [中国科大镜像站](http://mirrors.ustc.edu.cn/ubuntu-cdimage/releases/18.04/release/)/ubuntu-18.04-server-amd64.iso,安装后大约占用1.5G空间。经测试该安装程序并不稳定。 36 | 37 | 安装完的系统占用磁盘空间为3.5G。使用物理服务器或新建虚拟机都可以。如果使用虚拟机,选择4个虚拟CPU,2G内存,40G硬盘(如果想保存更多日志可以适当加大空间)一般就够用,类型可以选Ubuntu Linux(64-bit)。 38 | 39 | 使用光盘镜像引导,按提示安装即可,一般在10分钟内完成。安装过程中有疑问,请参考 40 | [Ubuntu 18.04 Server 版安装过程图文详解](https://blog.csdn.net/zhengchaooo/article/details/80145744)。 41 | 42 | 如果安装时设置了网络,安装过程中会连接官方服务器获取最新的软件包,因此请保持网络畅通。 43 | 44 | 如果安装时没有设置网络,请参见下面的 二、配置网络 部分。 45 | 46 | 注意:Ubuntu 系统要求必须使用一个普通用户登录,执行需要特权的命令时,使用`sudo ....`来临时切换为root用户进行。如果需要以root身份执行较多的命令,可以使用`sudo su -`切换为root用户(虽然不建议这样做),这样一来就不需要每次输入`sudo`了。 47 | 48 | 49 | ## 二、配置网络 50 | 51 | 反向代理服务器需要IPv4/IPv6的连通性,对外需要开放22、80、443端口,如果您有防火墙,请放开这些端口。 52 | 53 | 使用安装时设置的普通用户登录系统,使用以下命令测试网络是否正常: 54 | ```bash 55 | ip addr #查看网卡设置的ipv4/ipv6地址 56 | ip route #查看ipv4网关 57 | ip -f inet6 route #查看ipv6网关 58 | ping 202.38.64.1 #检查ipv4连通性 59 | ping6 2001:da8:d800::1 #检查ipv6连通性 60 | ``` 61 | 如果网络存在问题,请按照以下说明修改配置,直到网络正常。 62 | 63 | Ubuntu网络配置与之前的变化较大,采用netplan管理,配置文件存放在`/etc/netplan/*.yaml`。 64 | 65 | 下面是我使用的例子,文件是`/etc/netplan/50-cloud-init.yaml`,内容如下: 66 | 67 | 请根据自己的网络情况,修改文件,修改后执行`sudo netplan apply`应用即可。 68 | 69 | ``` 70 | network: 71 | version: 2 72 | ethernets: 73 | ens160: 74 | dhcp4: no 75 | addresses: [222.195.81.200/24,'2001:da8:d800:381::200/64'] 76 | gateway4: 222.195.81.1 77 | gateway6: 2001:da8:d800:381::1 78 | nameservers: 79 | addresses: [202.38.64.1,202.38.64.56] 80 | ``` 81 | 82 | ![#1589F0](https://placehold.it/15/1589F0/000000?text=+) 检查点:上述ping之类的命令测试网络正常。 83 | 84 | 网络正确配置后,可以从其他机器ssh连接Nginx服务器,以方便后续操作时,通过"拷贝-粘贴"运行命令。 85 | 86 | # 注意:以下 步骤三--步骤七 部分有快捷脚本可用,下载后执行即可全部完成,大大节省时间,请参见 十、快捷脚本 87 | 88 | ## 三、设置系统时区 89 | 90 | 默认安装的系统时区是UTC,以下命令可以修改为北京时间: 91 | ``` 92 | sudo timedatectl set-timezone Asia/Shanghai 93 | ``` 94 | 95 | ## 四、设置防火墙 96 | 97 | 安全是第一要务,对于Nginx服务器,对外需开通80、443端口,对部分地址开通22端口以方便管理。 98 | 99 | 使用如下命令设置,请根据自己的管理地址段,替换下面的`202.38.64.0/24` 100 | ```bash 101 | sudo ufw allow 80/tcp 102 | sudo ufw allow 443/tcp 103 | sudo ufw allow proto tcp from 202.38.64.0/24 to any port 22 104 | sudo ufw default deny 105 | sudo ufw enable 106 | ``` 107 | 您可以使用命令`sudo ufw status numbered`查看设置的规则,如果设置错误,可以使用`sudo ufw delete [序号]`删除规则。 108 | 109 | 如果您有强烈的好奇心,可以执行`sudo iptables -L -nv | more`看看系统实际使用的规则。 110 | 111 | ![#1589F0](https://placehold.it/15/1589F0/000000?text=+) 检查点:命令`sudo ufw status verbose`能看到设置的规则。 112 | 113 | ## 五、优化conntrack性能 114 | 115 | Linux系统防火墙需要使用conntrack模块记录tcp/udp的连接信息,默认的设置(最多6万连接)不太适合反向代理这种服务使用。 116 | 117 | 5.1 编辑文件`sudo vi /etc/modules`,增加2行: 118 | ```bash 119 | nf_conntrack_ipv4 120 | nf_conntrack_ipv6 121 | ``` 122 | 123 | 5.2 新建文件`sudo vi /etc/modprobe.d/nf_conntrack.conf`,增加1行(连接数是hashsize*8,按照以下设置,最多40万连接): 124 | ```bash 125 | options nf_conntrack hashsize=50000 126 | ``` 127 | 128 | 5.3 编辑文件`/etc/systemd/system/nginx.service.d/limit.conf`,增加2行: 129 | ``` 130 | mkdir /etc/systemd/system/nginx.service.d/ 131 | echo "[Service]" > /etc/systemd/system/nginx.service.d/limit.conf 132 | echo "LimitNOFILE=655360" >> /etc/systemd/system/nginx.service.d/limit.conf 133 | ``` 134 | 135 | 5.4 编辑文件`sudo vi /etc/sysctl.conf`,增加1行: 136 | ``` 137 | fs.file-max = 655360 138 | ``` 139 | 140 | 5.5 新建文件`sudo vi /etc/sysctl.d/90-conntrack.conf`,内容为: 141 | ``` 142 | net.netfilter.nf_conntrack_dccp_timeout_closereq = 60 143 | net.netfilter.nf_conntrack_dccp_timeout_closing = 60 144 | net.netfilter.nf_conntrack_dccp_timeout_open = 200 145 | net.netfilter.nf_conntrack_dccp_timeout_partopen = 60 146 | net.netfilter.nf_conntrack_dccp_timeout_request = 60 147 | net.netfilter.nf_conntrack_dccp_timeout_respond = 60 148 | net.netfilter.nf_conntrack_dccp_timeout_timewait = 60 149 | net.netfilter.nf_conntrack_frag6_timeout = 10 150 | net.netfilter.nf_conntrack_generic_timeout = 60 151 | net.netfilter.nf_conntrack_icmp_timeout = 10 152 | net.netfilter.nf_conntrack_icmpv6_timeout = 10 153 | net.netfilter.nf_conntrack_sctp_timeout_closed = 10 154 | net.netfilter.nf_conntrack_sctp_timeout_cookie_echoed = 3 155 | net.netfilter.nf_conntrack_sctp_timeout_cookie_wait = 3 156 | net.netfilter.nf_conntrack_sctp_timeout_established = 300 157 | net.netfilter.nf_conntrack_sctp_timeout_heartbeat_acked = 300 158 | net.netfilter.nf_conntrack_sctp_timeout_heartbeat_sent = 30 159 | net.netfilter.nf_conntrack_sctp_timeout_shutdown_ack_sent = 3 160 | net.netfilter.nf_conntrack_sctp_timeout_shutdown_recd = 0 161 | net.netfilter.nf_conntrack_sctp_timeout_shutdown_sent = 0 162 | net.netfilter.nf_conntrack_tcp_timeout_close = 10 163 | net.netfilter.nf_conntrack_tcp_timeout_close_wait = 10 164 | net.netfilter.nf_conntrack_tcp_timeout_established = 600 165 | net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 60 166 | net.netfilter.nf_conntrack_tcp_timeout_last_ack = 60 167 | net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 60 168 | net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 30 169 | net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 30 170 | net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30 171 | net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 30 172 | net.netfilter.nf_conntrack_udp_timeout = 10 173 | net.netfilter.nf_conntrack_udp_timeout_stream = 30 174 | ``` 175 | 176 | 设置完成后,重启系统。 177 | 178 | ![#1589F0](https://placehold.it/15/1589F0/000000?text=+) 检查点:重启后执行`dmesg | grep conn`会显示最大连接数为40万,`more /proc/sys/net/netfilter/*timeout*`会显示修改后的超时时间。 179 | 180 | ## 六、安装Nginx 181 | 182 | 执行`sudo apt install -y nginx`即可。 183 | 184 | ## 七、修改Nginx配置 185 | 186 | 建议使用Git跟踪配置的变化。 187 | 188 | 7.1 使用如下命令初始化(请修改自己的个人信息): 189 | ```bash 190 | sudo su - 191 | git config --global user.email "james@ustc.educ.cn" 192 | git config --global user.name "Zhang Huanje" 193 | 194 | cd /etc/nginx 195 | git init 196 | git add * 197 | git commit -m init 198 | ``` 199 | 200 | 7.2 生成Nginx需要的随机数(需要大约几分钟以搜集足够的随机信息): 201 | ```bash 202 | sudo mkdir /etc/nginx/ssl 203 | sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048 204 | ``` 205 | 206 | 7.3 下载配置文件模板。我们准备了一份模板,下载后稍加修改就可以使用。 207 | 208 | ``` 209 | cd /etc/nginx 210 | sudo mv nginx.conf nginx.system.conf 211 | sudo wget https://raw.githubusercontent.com/bg6cq/nginx-install/master/nginx.conf 212 | ``` 213 | 214 | 7.4 修改配置文件`sudo vi nginx.conf`,修改最后部分的配置,改为自己的主机名、日志文件名、IP地址。 215 | 216 | 最后部分配置如下,请修改主机名、日志文件名、IP地址(IP地址是网站的IPv4地址) 217 | ``` 218 | server { 219 | listen 80 ; 220 | listen [::]:80 ; 221 | server_name www.ustc.edu.cn; 222 | access_log /var/log/nginx/host.www.ustc.edu.cn.access.log main; 223 | location / { 224 | proxy_pass http://202.38.64.99/; 225 | } 226 | } 227 | } 228 | ``` 229 | 230 | 7.5 测试配置是否正确,下面是测试正确时的显示: 231 | ``` 232 | sudo nginx -t 233 | nginx: the configuration file /etc/nginx/nginx.conf syntax is ok 234 | nginx: configuration file /etc/nginx/nginx.conf test is successful 235 | ``` 236 | 237 | 7.6 如果测试正确,执行以下命令应用配置: 238 | ```bash 239 | systemctl restart nginx.service 240 | ``` 241 | 242 | ## 八、测试 243 | 244 | 在自己机器上修改hosts文件,如下所示(请用自己服务器的IPv6地址替换): 245 | ``` 246 | 2001:da8:d800:381::200 www.ustc.edu.cn 247 | ``` 248 | 测试是否可以访问,并可以查看Nginx服务器上`/var/log/nginx/`下的日志文件,看到有访问记录。 249 | 250 | ## 九、启用IPv6访问 251 | 252 | 经过测试访问正常后,可以修改DNS服务器上www.ustc.edu.cn的信息,增加 253 | 254 | ``` 255 | www IN AAAA 2001:da8:d800:381::200 256 | ```` 257 | 这样就能观察到IPv6的访问,您也可以到 [http://ipv6-test.com/validate.php](http://ipv6-test.com/validate.php) 处输入自己的网站地址测试IPv6的HTTP是否可以正常工作。 258 | 259 | 正常工作后,可以将配置文件的变更在git中提交,命令是: 260 | ```bash 261 | sudo su - 262 | cd /etc/nginx 263 | git add nginx.conf 264 | git commit -m "www.ustc.edu.cn ok" 265 | ``` 266 | 267 | 日志保留时间的调整,`vi /etc/logrotate.d/nginx`,把 268 | ``` 269 | rotate 14 270 | ``` 271 | 改为 272 | ``` 273 | rotate 200 274 | ``` 275 | 保留200天日志。或者自己写脚本每天定时转储日志。 276 | 277 | 278 | ## 十、快捷脚本 279 | 280 | 以上 三---七 部分,有快捷脚本可用,只要完成"二、网络配置",网络畅通时,执行以下脚本即可完成大部分配置,只要修改配置文件即可。 281 | 282 | 注意,执行脚本时,请根据自己的信息替换命令行参数(命令行中202.38.95.0/24是将来允许使用ssh登录服务器的网段)。 283 | 284 | ``` 285 | sudo su - 286 | cd / 287 | wget http://202.38.64.1/install-nginx.sh 288 | 289 | bash ./install-nginx.sh 202.38.95.0/24 290 | ``` 291 | 292 | 执行完脚本,重新启动,然后请参考 7.4 修改配置和后续工作 293 | 294 | ## 十一、HTTPS支持 295 | 296 | 警告:上海交大 章思宇 老师提醒,如果仅仅使用Nginx处理IPv6流量并支持HTTPS访问,同时处理IPv4流量的服务器不支持HTTPS,这时开通IPv6流量的HTTPS可能会带来负面影响,原因是有些搜索引擎会通过v6收录HTTPS的链接,导致v4用户不能访问。 297 | 298 | 避免这种情况出现需要在v4/v6上同时支持HTTPS访问,其中最简单的方式是把所有流量经过Nginx代理。中国科大已经这样用了10多年,在一台Nginx服务器上对教育网、电信、联通、移动出口提供服务,运行稳定。 299 | 300 | Let’s Encrypt是免费的证书签发站点,非常方便。如果不愿意购买证书,完全可以满足大部分站点的使用。 301 | 302 | 假定 http://testsite.ustc.edu.cn 已经由Nginx服务器代理,需要增加https支持,步骤如下: 303 | 304 | 注:以下命令均在`sudo su -`后执行 305 | 306 | 11.1 下载getssl,准备环境 307 | 308 | `/etc/nginx/ssl/web`是用来存放Let's Encrypt要用到随机数的目录 309 | 310 | ```bash 311 | mkdir /etc/nginx/ssl/web 312 | cd /etc/nginx 313 | curl --silent https://raw.githubusercontent.com/srvrco/getssl/master/getssl > getssl ; chmod 700 getssl 314 | ``` 315 | 316 | 11.2 在`/etc/nginx/nginx.conf`中增加 testsite.ustc.edu.cn 的配置,如下所示: 317 | ``` 318 | server { 319 | listen 80 ; 320 | listen [::]:80 ; 321 | server_name testsite.ustc.edu.cn; 322 | access_log /var/log/nginx/host.testsite.ustc.edu.cn.access.log main; 323 | location / { 324 | proxy_pass http://202.38.64.40/; 325 | } 326 | location /.well-known/ { 327 | root /etc/nginx/ssl/web/; 328 | } 329 | } 330 | ``` 331 | 332 | 测试配置正常后,应用 333 | ``` 334 | nginx -t && service nginx restart #这条命令也是可用的 335 | ``` 336 | 337 | 11.3 生成并修改getssl配置 338 | 339 | 生成配置(-U的含义是不检查getssl是否有新版本,会略快): 340 | ``` 341 | cd /etc/nginx 342 | ./getssl -U -c testsite.ustc.edu.cn 343 | ``` 344 | 345 | 会生成配置文件`/root/.getssl/getssl.cfg`和`/root/.getssl/testsite.ustc.edu.cn/getssl.cfg` 346 | 347 | 编辑文件`vi /root/.getssl/getssl.cfg`,修改3个地方(邮件是为了获取证书即将到期的通知) 348 | ``` 349 | CA="https://acme-v02.api.letsencrypt.org" 350 | ACCOUNT_EMAIL="james@ustc.edu.cn" 351 | #CHECK_REMOTE="true" 352 | ACL=('/etc/nginx/ssl/web/.well-known/acme-challenge') 353 | USE_SINGLE_ACL="true" 354 | ``` 355 | 356 | 编辑文件`vi /root/.getssl/testsite.ustc.edu.cn/getssl.cfg`,内容为: 357 | ``` 358 | DOMAIN_KEY_LOCATION="/etc/nginx/ssl/testsite.ustc.edu.cn.key" 359 | DOMAIN_CHAIN_LOCATION="/etc/nginx/ssl/testsite.ustc.edu.cn.pem" 360 | ``` 361 | 362 | 11.4 获取证书 363 | 364 | 执行如下命令获取证书(-d是调试开关,可以显示更多的调试信息): 365 | ``` 366 | cd /etc/nginx 367 | ./getssl -U -d testsite.ustc.edu.cn 368 | ``` 369 | 执行完毕后,会产生2个文件`/etc/nginx/ssl/testsite.ustc.edu.cn.key`和`/etc/nginx/ssl/testsite.ustc.edu.cn.pem`。 370 | 371 | 11.5 使用证书 372 | 373 | 修改nginx.conf文件,对应的配置如下(其中Content-Security-Policy可以让浏览器把页面中的http资源引用自动转换为https访问): 374 | ``` 375 | server { 376 | listen 80 ; 377 | listen [::]:80 ; 378 | server_name testsite.ustc.edu.cn; 379 | access_log /var/log/nginx/host.testsite.ustc.edu.cn.access.log main; 380 | location / { 381 | proxy_pass http://202.38.64.40/; 382 | } 383 | location /.well-known/ { 384 | root /etc/nginx/ssl/web/; 385 | } 386 | } 387 | server { 388 | listen 443 ssl http2; 389 | listen [::]:443 ssl http2; 390 | server_name testsite.ustc.edu.cn; 391 | ssl_certificate /etc/nginx/ssl/testsite.ustc.edu.cn.pem; 392 | ssl_certificate_key /etc/nginx/ssl/testsite.ustc.edu.cn.key; 393 | add_header Strict-Transport-Security $hsts_header; 394 | add_header Content-Security-Policy upgrade-insecure-requests; 395 | access_log /var/log/nginx/host.testsite.ustc.edu.cn.access.log main; 396 | location / { 397 | proxy_pass http://202.38.64.40/; 398 | } 399 | } 400 | ``` 401 | 402 | 11.6 测试配置正常后,应用 403 | 404 | ``` 405 | nginx -t && systemctl restart nginx.service 406 | ``` 407 | 408 | 这时可以通过 https://testsite.ustc.edu.cn 访问,也可以使用[SSL Labs](https://www.ssllabs.com/ssltest/analyze.html)测试网站的SSL得分情况。 409 | 410 | 411 | 正常工作后,可以将配置文件的变更在git中提交,命令是: 412 | ```bash 413 | sudo su - 414 | cd /etc/nginx 415 | git add nginx.conf 416 | git commit -m "https://testsite.ustc.edu.cn ok" 417 | ``` 418 | 419 | 11.7 证书更新 420 | 421 | Let's Encrypt 证书有效期为90天,建议在60天时进行更新,更新的命令是; 422 | ``` 423 | cd /etc/nginx 424 | ./getssl -U testsite.ustc.edu.cn 425 | nginx -t && systemctl restart nginx.service 426 | ``` 427 | 428 | 11.8 强制用户使用https访问 429 | 430 | 上述设置,只要用户访问过 https://testsite.ustc.edu.cn ,在604800秒,即7天内,总是会用https方式访问。 431 | 432 | 如果HTTPS运行稳定,可以强制useragent带有Mozila/5.0(较新的浏览器)的访问强制使用https访问,将配置改为如下: 433 | 434 | ``` 435 | server { 436 | listen 80 ; 437 | listen [::]:80 ; 438 | server_name testsite.ustc.edu.cn; 439 | access_log /var/log/nginx/host.testsite.ustc.edu.cn.access.log main; 440 | location / { 441 | if ( $http_user_agent ~ "(Mozilla/5.0)" ) { 442 | return 301 https://$server_name$request_uri; 443 | } 444 | proxy_pass http://202.38.64.40/; 445 | } 446 | location /.well-known/ { 447 | root /etc/nginx/ssl/web/; 448 | } 449 | } 450 | server { 451 | listen 443 ssl http2; 452 | listen [::]:443 ssl http2; 453 | server_name testsite.ustc.edu.cn; 454 | ssl_certificate /etc/nginx/ssl/testsite.ustc.edu.cn.pem; 455 | ssl_certificate_key /etc/nginx/ssl/testsite.ustc.edu.cn.key; 456 | add_header Strict-Transport-Security $hsts_header; 457 | add_header Content-Security-Policy upgrade-insecure-requests; 458 | access_log /var/log/nginx/host.testsite.ustc.edu.cn.access.log main; 459 | location / { 460 | proxy_pass http://202.38.64.40/; 461 | } 462 | } 463 | ``` 464 | 465 | 11.9 Let's Encrypt 证书的数量和频度限制 466 | 467 | 对使用影响最大的是Let's Encrypt 证书的频度限制,每7天仅仅允许申请20个证书,到达这个限制后,已有的证书仍旧可以更新。 468 | 469 | 因此如果域名下有大量网站需要代理,可以使用 \*.ustc.edu.cn 之类的通配符证书,申请一个证书供多个网站使用。 470 | 471 | ## 十二、Nginx状态监视 472 | 473 | Nginx运行时的连接信息对运行很有用,下面的操作完成后,可以提供类似 [http://202.38.64.1/nginx](http://202.38.64.1/nginx/) 的统计图。 474 | 475 | 注:以下命令均在`sudo su -`后执行 476 | 477 | ```bash 478 | mkdir /usr/share/nginx/html/status/ 479 | apt install -y librrds-perl libwww-perl rrdtool 480 | wget https://raw.githubusercontent.com/bg6cq/nginx-install/master/rrd_nginx.pl -O /etc/nginx/rrd_nginx.pl 481 | wget https://raw.githubusercontent.com/bg6cq/nginx-install/master/status_index.html -O /usr/share/nginx/html/status/index.html 482 | 483 | rrdtool create /usr/share/nginx/html/status/nginx.rrd -s 60 \ 484 | DS:requests:COUNTER:120:0:100000 \ 485 | DS:total:GAUGE:120:0:60000 \ 486 | DS:reading:GAUGE:120:0:60000 \ 487 | DS:writing:GAUGE:120:0:60000 \ 488 | DS:waiting:GAUGE:120:0:60000 \ 489 | RRA:AVERAGE:0.5:1:2880 \ 490 | RRA:AVERAGE:0.5:30:672 \ 491 | RRA:AVERAGE:0.5:120:732 \ 492 | RRA:AVERAGE:0.5:720:1460 493 | ``` 494 | 然后执行`crontab -e`设置以下定时任务: 495 | ``` 496 | * * * * * perl /etc/nginx/rrd_nginx.pl 497 | ``` 498 | 过一会,就可以使用 http://x.x.x.x/status (x.x.x.x是Nginx服务器IP地址) 查看状态页面。 499 | 500 | 如果仅仅允许部分IP查看状态页面,可以修改nginx.conf中,增加IP地址限制。 501 | 502 | 如果都工作正常,可以把相关修改在git中提交,命令是: 503 | ```bash 504 | sudo su - 505 | cd /etc/nginx 506 | git add rrd_nginx.pl 507 | git commit -m "rrd_nginx" 508 | ``` 509 | 510 | ## 十三、系统和软件的更新 511 | 512 | 一直到2023年,Ubuntu都会为 Ubuntu 18.04 LTS提供软件更新服务。只要执行以下命令,即可将系统中软件更新: 513 | ``` 514 | sudo apt update 515 | sudo apt upgrade 516 | ``` 517 | 518 | 519 | *** 520 | 欢迎 [加入我们整理资料](https://github.com/bg6cq/ITTS) 521 | -------------------------------------------------------------------------------- /images/steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bg6cq/nginx-install/79b4d31cee52a8bf771848dae1a6743d424cd6d3/images/steps.png -------------------------------------------------------------------------------- /images/steps.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bg6cq/nginx-install/79b4d31cee52a8bf771848dae1a6743d424cd6d3/images/steps.pptx -------------------------------------------------------------------------------- /install-nginx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ ! $# -eq 1 ]; then 4 | echo bash ./install-nginx.sh x.x.x.x/24 5 | echo x.x.x.x is your ssh client network 6 | echo such as 202.38.64.0/24 7 | exit 8 | fi 9 | 10 | if [ -f /etc/nginx/nginx.conf ]; then 11 | echo "/etc/nginx/nginx.conf exist, exit"; 12 | exit 13 | fi 14 | 15 | id | grep root 16 | retcode=$? 17 | if [ $retcode -eq 1 ]; then 18 | echo you are not using root 19 | exit 20 | fi 21 | 22 | echo install nginx 23 | echo ssh client is $1 24 | 25 | echo ============= step 3 26 | timedatectl set-timezone Asia/Shanghai 27 | 28 | echo ============= step 4 29 | ufw enable 30 | ufw allow 80/tcp 31 | ufw allow 443/tcp 32 | ufw allow proto tcp from $1 to any port 22 33 | ufw default deny 34 | 35 | echo ============= step 5.1 36 | echo nf_conntrack_ipv4 >> /etc/modules 37 | echo nf_conntrack_ipv6 >> /etc/modules 38 | 39 | echo ============= step 5.2 40 | echo "options nf_conntrack hashsize=50000" > /etc/modprobe.d/nf_conntrack.conf 41 | 42 | echo ============= step 5.3 43 | mkdir /etc/systemd/system/nginx.service.d/ 44 | echo "[Service]" > /etc/systemd/system/nginx.service.d/limit.conf 45 | echo "LimitNOFILE=655360" >> /etc/systemd/system/nginx.service.d/limit.conf 46 | 47 | echo ============= step 5.4 48 | echo "fs.file-max = 655360" >> /etc/sysctl.conf 49 | 50 | echo ============= step 5.5 51 | cat << EOF > /etc/sysctl.d/90-conntrack.conf 52 | net.netfilter.nf_conntrack_dccp_timeout_closereq = 60 53 | net.netfilter.nf_conntrack_dccp_timeout_closing = 60 54 | net.netfilter.nf_conntrack_dccp_timeout_open = 200 55 | net.netfilter.nf_conntrack_dccp_timeout_partopen = 60 56 | net.netfilter.nf_conntrack_dccp_timeout_request = 60 57 | net.netfilter.nf_conntrack_dccp_timeout_respond = 60 58 | net.netfilter.nf_conntrack_dccp_timeout_timewait = 60 59 | net.netfilter.nf_conntrack_frag6_timeout = 10 60 | net.netfilter.nf_conntrack_generic_timeout = 60 61 | net.netfilter.nf_conntrack_icmp_timeout = 10 62 | net.netfilter.nf_conntrack_icmpv6_timeout = 10 63 | net.netfilter.nf_conntrack_sctp_timeout_closed = 10 64 | net.netfilter.nf_conntrack_sctp_timeout_cookie_echoed = 3 65 | net.netfilter.nf_conntrack_sctp_timeout_cookie_wait = 3 66 | net.netfilter.nf_conntrack_sctp_timeout_established = 300 67 | net.netfilter.nf_conntrack_sctp_timeout_heartbeat_acked = 300 68 | net.netfilter.nf_conntrack_sctp_timeout_heartbeat_sent = 30 69 | net.netfilter.nf_conntrack_sctp_timeout_shutdown_ack_sent = 3 70 | net.netfilter.nf_conntrack_sctp_timeout_shutdown_recd = 0 71 | net.netfilter.nf_conntrack_sctp_timeout_shutdown_sent = 0 72 | net.netfilter.nf_conntrack_tcp_timeout_close = 10 73 | net.netfilter.nf_conntrack_tcp_timeout_close_wait = 10 74 | net.netfilter.nf_conntrack_tcp_timeout_established = 600 75 | net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 60 76 | net.netfilter.nf_conntrack_tcp_timeout_last_ack = 60 77 | net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 60 78 | net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 30 79 | net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 30 80 | net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30 81 | net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 30 82 | net.netfilter.nf_conntrack_udp_timeout = 10 83 | net.netfilter.nf_conntrack_udp_timeout_stream = 30 84 | EOF 85 | 86 | echo ============= step 6 87 | apt install -y nginx git 88 | 89 | echo ============= step 7.2 90 | sudo mkdir /etc/nginx/ssl 91 | sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048 92 | 93 | echo ============= step 7.3 94 | cd /etc/nginx 95 | mv nginx.conf nginx.system.conf 96 | wget https://raw.githubusercontent.com/bg6cq/nginx-install/master/nginx.conf 97 | 98 | 99 | echo end of script 100 | echo now please do a reboot!!! 101 | echo 102 | echo after boot up, please do the following 103 | echo vi /etc/nginx/nginx.conf 104 | echo nginx -t 105 | echo 106 | -------------------------------------------------------------------------------- /nginx.conf: -------------------------------------------------------------------------------- 1 | user www-data; 2 | worker_processes auto; 3 | worker_rlimit_nofile 20480; 4 | pid /run/nginx.pid; 5 | include /etc/nginx/modules-enabled/*.conf; 6 | 7 | events { 8 | worker_connections 10240; 9 | # multi_accept on; 10 | } 11 | 12 | http { 13 | 14 | ## 15 | # Basic Settings 16 | ## 17 | 18 | sendfile on; 19 | tcp_nopush on; 20 | tcp_nodelay on; 21 | keepalive_timeout 65; 22 | types_hash_max_size 2048; 23 | server_tokens off; 24 | 25 | server_names_hash_bucket_size 128; 26 | # server_name_in_redirect off; 27 | 28 | include /etc/nginx/mime.types; 29 | default_type application/octet-stream; 30 | 31 | ## 32 | # SSL Settings 33 | ## 34 | 35 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE 36 | ssl_prefer_server_ciphers on; 37 | ssl_session_cache shared:SSL:5m; 38 | ssl_session_timeout 30m; 39 | 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:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; 40 | ssl_dhparam /etc/nginx/ssl/dhparam.pem; 41 | 42 | ## 43 | # Logging Settings 44 | ## 45 | 46 | log_format main '$remote_addr - $remote_user [$time_local] "$ssl_protocol/$ssl_cipher" "$request" ' 47 | '"$status" $body_bytes_sent "$http_referer" ' 48 | '"$http_user_agent" "$http_x_forwarded_for"'; 49 | log_format nohost '$host $remote_addr [$time_local] "$request" ' 50 | '"$status" $body_bytes_sent "$http_referer" ' 51 | '"$http_user_agent" "$http_x_forwarded_for"'; 52 | 53 | access_log /var/log/nginx/access.log; 54 | error_log /var/log/nginx/error.log; 55 | 56 | ## 57 | # Gzip Settings 58 | ## 59 | 60 | # gzip on; 61 | 62 | # gzip_vary on; 63 | # gzip_proxied any; 64 | # gzip_comp_level 6; 65 | # gzip_buffers 16 8k; 66 | # gzip_http_version 1.1; 67 | # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; 68 | 69 | ## 70 | # Virtual Host Configs 71 | ## 72 | 73 | # include /etc/nginx/conf.d/*.conf; 74 | # include /etc/nginx/sites-enabled/*; 75 | 76 | proxy_set_header Host $host; 77 | proxy_set_header X-Real-IP $remote_addr; 78 | proxy_set_header X-Forwarded-Proto $scheme; 79 | 80 | map $scheme $hsts_header { 81 | https "max-age=604800"; 82 | } 83 | 84 | 85 | server { #不存在或恶意解析处理 86 | listen 80 default_server; 87 | listen [::]:80 default_server; 88 | server_name _; 89 | access_log /var/log/nginx/host.nohost.ustc.edu.cn.access.log nohost; 90 | default_type 'text/html'; 91 | location / { 92 | return 404 "404 Unknown Virtual Host

404 Unknown Virtual Host

client: $remote_addr, request_host: $host, time: $date_local

您访问的域名不存在或已被关闭

如有问题请联系系统管理员
"; 93 | } 94 | location /nginx_status { 95 | stub_status on; 96 | access_log off; 97 | allow 127.0.0.1; 98 | deny all; 99 | } 100 | location /status { 101 | root /usr/share/nginx/html/; 102 | } 103 | 104 | } 105 | 106 | #配置模版1,重定向配置,访问这个主机直接重定向到一个页面 107 | # server { 108 | # listen 80 ; 109 | # listen [::]:80 ; 110 | # listen 443 ssl http2; 111 | # listen [::]:443 ssl http2; 112 | # server_name redir.ustc.edu.cn; 113 | # ssl_certificate /etc/nginx/ssl/redir.ustc.edu.cn.pem; 114 | # ssl_certificate_key /etc/nginx/ssl/redir.ustc.edu.cn.key; 115 | # access_log /var/log/nginx/host.redir.ustc.edu.cn.access.log main; 116 | # location / { 117 | # rewrite ^ http://www.ustc.edu.cn/url/dir; 118 | # } 119 | # location /.well-known/ { 120 | # root /etc/nginx/ssl/web/; 121 | # } 122 | # } 123 | 124 | 125 | # 126 | #配置模版2,http重定向到https(useragent 带有 Mozila/5.0),用于强制把http访问用户重定向到https 127 | # 128 | # server { 129 | # listen 80; 130 | # listen [::]:80; 131 | # server_name www.ustc.edu.cn; 132 | # access_log /var/log/nginx/host.www.ustc.edu.cn.access.log main; 133 | # location / { 134 | # if ( $http_user_agent ~ "(Mozilla/5.0)" ) { 135 | # return 301 https://$server_name$request_uri; 136 | # } 137 | # proxy_pass http://202.38.64.99/; 138 | # } 139 | # location /.well-known/ { 140 | # root /etc/nginx/ssl/web/; 141 | # } 142 | # } 143 | # server { 144 | # listen 443 ssl http2; 145 | # listen [::]:443 ssl http2; 146 | # server_name www.ustc.edu.cn; 147 | # ssl_certificate /etc/nginx/ssl/www.ustc.edu.cn.pem; 148 | # ssl_certificate_key /etc/nginx/ssl/www.ustc.edu.cn.key; 149 | # access_log /var/log/nginx/host.www.ustc.edu.cn.access.log main; 150 | # add_header Strict-Transport-Security $hsts_header; 151 | # add_header Content-Security-Policy upgrade-insecure-requests; 152 | # location / { 153 | # proxy_pass http://202.38.64.99/; 154 | # } 155 | #} 156 | 157 | #配置模版3,http对外服务网站 158 | # server { 159 | # listen 80 ; 160 | # listen [::]:80 ; 161 | # server_name www.ustc.edu.cn; 162 | # access_log /var/log/nginx/host.www.ustc.edu.cn.access.log main; 163 | # location / { 164 | # proxy_pass http://202.38.64.99/; 165 | # } 166 | # } 167 | 168 | 169 | #测试配置, 请修改下面的主机名、日志文件名和对应的IP地址 170 | server { 171 | listen 80 ; 172 | listen [::]:80 ; 173 | server_name www.ustc.edu.cn; 174 | access_log /var/log/nginx/host.www.ustc.edu.cn.access.log main; 175 | location / { 176 | proxy_pass http://202.38.64.99/; 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /rrd_nginx.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use RRDs; 3 | use LWP::UserAgent; 4 | 5 | # define location of rrdtool databases 6 | my $rrd = '/usr/share/nginx/html/status'; 7 | # define location of images 8 | my $img = '/usr/share/nginx/html/status'; 9 | # define your nginx stats URL 10 | my $URL = "http://127.0.0.1/nginx_status"; 11 | 12 | my $ua = LWP::UserAgent->new(timeout => 30); 13 | $ua->agent(""); 14 | my $response = $ua->request(HTTP::Request->new('GET', $URL)); 15 | 16 | my $requests = 0; 17 | my $total = 0; 18 | my $reading = 0; 19 | my $writing = 0; 20 | my $waiting = 0; 21 | 22 | foreach (split(/\n/, $response->content)) { 23 | $total = $1 if (/^Active connections:\s+(\d+)/); 24 | if (/^Reading:\s+(\d+).*Writing:\s+(\d+).*Waiting:\s+(\d+)/) { 25 | $reading = $1; 26 | $writing = $2; 27 | $waiting = $3; 28 | } 29 | $requests = $3 if (/^\s+(\d+)\s+(\d+)\s+(\d+)/); 30 | } 31 | 32 | # print "RQ:$requests; TT:$total; RD:$reading; WR:$writing; WA:$waiting\n"; 33 | 34 | # if rrdtool database doesn't exist, create it 35 | if (! -e "$rrd/nginx.rrd") { 36 | RRDs::create "$rrd/nginx.rrd", 37 | "-s 60", 38 | "DS:requests:COUNTER:120:0:100000", 39 | "DS:total:GAUGE:120:0:60000", 40 | "DS:reading:GAUGE:120:0:60000", 41 | "DS:writing:GAUGE:120:0:60000", 42 | "DS:waiting:GAUGE:120:0:60000", 43 | "RRA:AVERAGE:0.5:1:2880", 44 | "RRA:AVERAGE:0.5:30:672", 45 | "RRA:AVERAGE:0.5:120:732", 46 | "RRA:AVERAGE:0.5:720:1460"; 47 | } 48 | 49 | # insert values into rrd database 50 | RRDs::update "$rrd/nginx.rrd", 51 | "-t", "requests:total:reading:writing:waiting", 52 | "N:$requests:$total:$reading:$writing:$waiting"; 53 | 54 | # Generate graphs 55 | CreateGraphs("day"); 56 | CreateGraphs("week"); 57 | CreateGraphs("month"); 58 | CreateGraphs("year"); 59 | 60 | #------------------------------------------------------------------------------ 61 | sub CreateGraphs($){ 62 | my $period = shift; 63 | 64 | RRDs::graph "$img/requests-$period.png", 65 | "-s -1$period", 66 | "-t Requests on nginx", 67 | "--lazy", 68 | "-h", "150", "-w", "700", 69 | "-l 0", 70 | "-a", "PNG", 71 | "-v requests/sec", 72 | "DEF:requests=$rrd/nginx.rrd:requests:AVERAGE", 73 | "LINE2:requests#336600:Requests", 74 | "GPRINT:requests:MAX: Max\\: %5.1lf %S", 75 | "GPRINT:requests:AVERAGE: Avg\\: %5.1lf %S", 76 | "GPRINT:requests:LAST: Current\\: %5.1lf %Sreq/sec", 77 | "HRULE:0#000000"; 78 | if ($ERROR = RRDs::error) { 79 | print "$0: unable to generate $period graph: $ERROR\n"; 80 | } 81 | 82 | RRDs::graph "$img/connections-$period.png", 83 | "-s -1$period", 84 | "-t Connections on nginx", 85 | "--lazy", 86 | "-h", "150", "-w", "700", 87 | "-l 0", 88 | "-a", "PNG", 89 | "-v connections", 90 | "DEF:total=$rrd/nginx.rrd:total:AVERAGE", 91 | "DEF:reading=$rrd/nginx.rrd:reading:AVERAGE", 92 | "DEF:writing=$rrd/nginx.rrd:writing:AVERAGE", 93 | "DEF:waiting=$rrd/nginx.rrd:waiting:AVERAGE", 94 | 95 | "LINE2:total#22FF22:Total", 96 | "GPRINT:total:LAST: Current\\: %5.1lf %S", 97 | "GPRINT:total:MIN: Min\\: %5.1lf %S", 98 | "GPRINT:total:AVERAGE: Avg\\: %5.1lf %S", 99 | "GPRINT:total:MAX: Max\\: %5.1lf %S\\n", 100 | 101 | "LINE2:reading#0022FF:Reading", 102 | "GPRINT:reading:LAST: Current\\: %5.1lf %S", 103 | "GPRINT:reading:MIN: Min\\: %5.1lf %S", 104 | "GPRINT:reading:AVERAGE: Avg\\: %5.1lf %S", 105 | "GPRINT:reading:MAX: Max\\: %5.1lf %S\\n", 106 | 107 | "LINE2:writing#FF0000:Writing", 108 | "GPRINT:writing:LAST: Current\\: %5.1lf %S", 109 | "GPRINT:writing:MIN: Min\\: %5.1lf %S", 110 | "GPRINT:writing:AVERAGE: Avg\\: %5.1lf %S", 111 | "GPRINT:writing:MAX: Max\\: %5.1lf %S\\n", 112 | 113 | "LINE2:waiting#00AAAA:Waiting", 114 | "GPRINT:waiting:LAST: Current\\: %5.1lf %S", 115 | "GPRINT:waiting:MIN: Min\\: %5.1lf %S", 116 | "GPRINT:waiting:AVERAGE: Avg\\: %5.1lf %S", 117 | "GPRINT:waiting:MAX: Max\\: %5.1lf %S\\n", 118 | 119 | "HRULE:0#000000"; 120 | if ($ERROR = RRDs::error) { 121 | print "$0: unable to generate $period graph: $ERROR\n"; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /status_index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Nginx运行状态 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
day
week
month
year
26 | 27 | 28 | --------------------------------------------------------------------------------