记一次在局域网搭网站

在学校里用自己电脑( Windows10 环境)当服务器搭了个网站,仅可在校园网下访问,图一乐。

基础

安装 flask 框架

Flask 是一个好用且简单的 web 框架,更多操作可以参考 Flask官网
pip install flask
当然前提得先装好 python ,不提。
在 VSCode 下可以直接用 Code runner 运行下面代码。

1
2
3
4
5
6
7
8
9
10
11
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World!'
if __name__ == '__main__':
app.run(
host='0.0.0.0', # 加了这个参数局域网内部才可以通过本机ip访问
port=5000, # 端口也可以设成80,访问的时候不用加端口号
debug=True, # 开启调试模式,可以实时监控代码更改
)

这样,一个基础的网页就搭建好了,在同一个局域网用浏览器访问 http://<你电脑的内网IP>:5000 就能看到 Hello World! 了。
但是我在连着无线网的笔记本部署却不能访问,也 ping 不通笔记本的 ip ,其中原因有待细究。

更新:无线网无法访问是因为学校防挖矿病毒,把低端口封了。

进阶

Nginx

有域名的可以下个 Nginx 玩,体验感高很多(bushi)。
Nginx 下载地址 http://nginx.org/en/download.html
建议下载稳定版的,即 Stable version
下载后直接解压即可,不要双击 Nginx.exe。用终端打开 Nginx 的目录,然后使用命令 start nginx 运行。
以下是一些 Nginx 的常用命令:( Windows 下没有添加环境变量的情况下 nginx 需要换成 ./nginx xxx )

1
2
3
4
nginx -s reload # 重载配置文件,更改配置文件后记得重载
nginx -s reopen # 重启Nginx
nginx -s stop # 强行停止Nginx
nginx -s quit # 正常退出Nginx

有个小坑就是有时不一定能通过上面的两个命令停止 Nginx ,这时在任务管理器是能看见 Nginx 的进程还在的,需要手动杀掉,否则可能无法正常重载配置文件(即 config 文件)。
同时觉得用命令行太麻烦了,就写了个 Python 的脚本配合 Flask 操作,如下:

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
from subprocess import Popen, PIPE
import psutil
import os
class Nginx:
def __init__(self, path):
self.path = path # Nginx的目录(绝对路径)
def start(self):
obj = Popen("start nginx",cwd=self.path, shell=True, stdout=PIPE, stderr=PIPE)
def quit(self):
obj = Popen("nginx -s quit",cwd=self.path, shell=True, stdout=PIPE, stderr=PIPE)
out_info, out_error = obj.communicate()
return (out_info, out_error)
def reload(self):
obj = Popen("nginx -s reload",cwd=self.path, shell=True, stdout=PIPE, stderr=PIPE)
out_info, out_error = obj.communicate()
return (out_info, out_error)
def restart(self):
obj = Popen("nginx -s reopen",cwd=self.path, shell=True, stdout=PIPE, stderr=PIPE)
out_info, out_error = obj.communicate()
return (out_info, out_error)
def killall(self):
pids = psutil.pids()
for pid in pids:
p = psutil.Process(pid)
if p.name() == 'nginx.exe':
print(pid)
p.kill()
def status(self):
pids = psutil.pids()
nginxpid=[]
for pid in pids:
p = psutil.Process(pid)
if p.name() == 'nginx.exe':
nginxpid.append(pid)
if len(nginxpid)==0:
return('Nginx未运行')
else:
return('%d 个Nginx进程正在运行中' % len(nginxpid))

nginx.conf 文件(即 Nginx 配置文件,位于 Nginx 的 conf 目录下)的 server 配置如下:

1
2
3
4
5
6
7
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:5000;
}
}

proxy_pass 后面那个地址必须是本地能访问的,此时我已经将上面python代码中的 host='0.0.0.0' 删掉了。
server_name 后面填写域名,记得要先添加 A 记录到局域网 ip ,我为了图方便直接添加了泛域名解析(即 *.example.com )。

SSL证书

证书申请

由于个人有一丢丢强迫症,看到浏览器 http 的不安全提示总是有点膈应,就想着部署个 SSL 证书解决。然而,其中过程非常麻烦,我最终还是在阿里租的服务器上用宝塔申请了个 Let’s Encrypt 证书(免费的,白嫖永不过时),然后一开始浏览器竟然显示证书是我那个服务器用的域名,折腾了两下换回去又好了,也是莫名其妙的。

更新:
https://letsencrypt.osfipin.com/
这个网站似乎不错

一些问题

DNS 的验证逻辑非常奇怪,建议添加 TXT 记录后等待10分钟左右再提交验证申请(我就是栽了几次都验证失败,浪费好多时间)。同时我在 Windows 用 Certbot 申请的时候出现了写入权限的错误,也是莫名其妙的,既然日志文件都能写在目录下,证书却写不了。

Nginx配置

如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
server {
listen 80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:5000;
}
# 强制使用 HTTPS,可选
# if ($server_port !~ 443) {
# rewrite ^(/.*)$ https://$host$1 permanent;
# }

ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_certificate 证书文件路径;
ssl_certificate_key 私钥文件路径;

ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;

ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
}
作者

未央

发布于

2022-03-17

更新于

2024-03-26

许可协议

评论