记一次在局域网搭网站

基础

安装 flask 框架

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

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 )

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

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

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 配置如下:

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 配置

如下:

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;
}
文章作者weyung
文章链接https://weyung.cc/posts/c9820b90/
许可协议CC BY-NC-SA 4.0
上一篇

下一篇

Code-server 配置