Shynet配置https服务
Shynet配置https服务

Shynet配置https服务

一、前情概要:

皇天不负有心人,前面用了将近两天的时间,完成了Shynet的搭建,这次又用了接近一天半的时间,才完成本次的Shynet适配HTTPS。没想到查找了很多文档,都没有结论,回过头来才发现,是自己太笨。

本教程将介绍如何给Shynet配置https服务。上一章讲述了通过Docker配置Shynet,通过Docker容器安装PostgreSQL以及安装并配置Shynet。当时我提到自己还不知道怎么配置HTTPS,这次配置HTTPS成功并把经验分享给大家,算是原创吧。

还要注意的一点是,配置HTTPS服务后,前台访问也要用HTTPS协议,如果用HTTP协议就会无法访问。

二、搭建环境

1)Docker version 25.0.3, build 4debf41

2)CentOS Linux release 7.9.2009 (Core)

三、配置Shynet文件

1、传入SSL配置文件

首先,我们将SSL证书下载到服务,然后我们通过docker cp命令,将SSL证书传入到Docker容器中。

docker cp /var/certificate/fangjunyu.com_bundle.crt shynet:/usr/src/shynet/
Successfully copied 6.14kB to shynet:/usr/src/shynet/

因为Docker的cp命令只支持单个文件的传递,如果用 docker cp /var/* 等通配符的话,就会报错,因此需要把Shynet SSL配置需要的pem和key证书逐个传入。

特别注意的是,关于证书或者其他需要传入的文件,其权限建议全部修改为 777,即

chmod 777 <file>

这样在配置方面就会减少报错,因为Docker的容器内用户权限很低,也不能用 sudo命令,因此需要先通过 docker cp命令把文件传输到容器外,修改后,再重新拷贝回容器内。

2、编辑Shynet配置文件

首先,在服务器上执行下面的命令,将容器内的 ssl.webserver.sh 和 entrypoint.sh 文件拷贝出来。

docker cp shynet:/usr/src/shynet/entrypoint.sh /var/tmp
Successfully copied 2.05kB to /var/tmp
docker cp shynet:/usr/src/shynet/ssl.webserver.sh /var/tmp
Successfully copied 2.05kB to /var/tmp

1)ssl.webserver 文件内容

#!/bin/bash

# Start Gunicorn processes
echo Launching Shynet web server...
exec gunicorn shynet.wsgi:application \
    --bind 0.0.0.0:${PORT:-8080} \
    --workers ${NUM_WORKERS:-1} \
    --timeout 100 \
    --certfile=/usr/src/shynet/fangjunyu.com_bundle.pem \
--keyfile=/usr/src/shynet/fangjunyu.com.key

注意:端口和其他信息都不要变,只需要修改pem和key证书即可,证书为Docker容器内的绝对位置。

2)entrypoint.sh文件内容

cat /var/tmp/entrypoint.sh
#!/bin/bash

if [[ ! $PERFORM_CHECKS_AND_SETUP == False ]]; then
  ./startup_checks.sh && exec ./ssl.webserver.sh
  else
  exec ./ssl.webserver.sh
fi

原文件是 webserver.sh 文件,你需要把他们修改为ssl.webserver.sh文件,这是最关键的一点。

然后修改他们的权限

chmod 777 /var/tmp/ssl.webserver.sh
chmod 777 /var/tmp/entrypoint.sh

因为Docker容器内的权限很低,因此建议把修改的文件权限调到最大,这样就可以在容器内修改和运行该文件。

最后,把修改后的文件,重新传回Docker容器

docker cp /var/tmp/entrypoint.sh shynet:/usr/src/shynet/             
Successfully copied 2.05kB to shynet:/usr/src/shynet/
docker cp /var/tmp/ssl.webserver.sh shynet:/usr/src/shynet/
Successfully copied 2.05kB to shynet:/usr/src/shynet/

对于基础薄弱的人来配置Shynet的HTTPS服务,最苦恼的恐怕就是这里。因为你不知道应该如何来配置Docker执行的主服务以及如何启动他。

我在这里进一步补充一下Docker容器内的文件知识:

  • ssl.webserver.sh: 一个脚本文件,可能用于配置或启动 Web 服务器的 SSL/TLS 设置。
  • entrypoint.sh: 一个入口脚本文件,通常用于容器启动时执行的初始化操作。
  • manage.py: 一个 Python 管理脚本,通常与 Django 或者类似的 Web 框架相关。
  • startup_checks.sh: 一个脚本文件,可能用于容器启动时执行的健康检查或初始化操作。
  • celeryworker.sh: 一个脚本文件,可能用于启动 Celery worker 进程。
  • pyproject.toml: Python 项目配置文件,通常与 Poetry 项目管理工具相关。
  • webserver.sh: 一个脚本文件,可能用于配置或启动 Web 服务器。

当你了解到这一切,你就知道,你应该修改 entrypoint.sh 文件的配置内容,来实现你想要的一切。

3、启动Shynet服务

重新启动容器,执行下面的命令:

docker restart <容器名称 / 容器id>

最后,访问前台正常打开。

当你看到这里,想必也完成的配置。那么,恭喜你,为自己的网站搭建了一个流量监控工具,可以更好的维护你的网站了。下面是HTTPS下的部分截图。

四、踩坑日记

1、Shynet的Js文件无法加载问题。

这个问题目前有两种情况:

一是Shynet跟踪的文件中,协议是HTTPS,但是你的Shynet并没有配置Https协议,就导致文件是无法加载的。

二是你的网页是HTTPS,但是你只能打开HTTP的跟踪文件,你错误的把协议改成HTTP,这可能会导致不同源的问题,因为HTTPS网页无法打开HTTP的资源。

    解决方法就是,如果你的网页是HTTPS协议,你就需要在Docker中把HTTPS配置上,就是前面提到的修改 entrypoint.sh 和 ssl.webserver.sh,这两个文件。

2、Shynet可以登录,但是登录用户后报错

这个问题,我遇到过,但是当时没有截图。具体的场景是使用Nginx通过HTTPS代理HTTPS,但是因为Shynet没有配置HTTPS,这导致Nginx把HTTPS服务转给Shynet时,Shynet只支持HTTP。

因此,就会报错,好像是

Forbidden (403)
CSRF verification failed. Request aborted.

More information is available with DEBUG=True.

这个问题的解决办法,就是给Shynet配置HTTPS。

3、Django 应用程序收到了一个无效的 HTTP_HOST 头部

下面是Shynet配置过程中的一个常见报错

User
[2024-04-02 05:35:43 +0000] [1295] [INFO] Booting worker with pid: 1295
ERROR Invalid HTTP_HOST header: '111.231.22.116:8080'. You may need to add '111.231.22.116' to ALLOWED_HOSTS.
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/django/core/handlers/exception.py", line 56, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.10/site-packages/django/utils/deprecation.py", line 135, in __call__
    response = self.process_request(request)
  File "/usr/local/lib/python3.10/site-packages/django/middleware/common.py", line 48, in process_request
    host = request.get_host()
  File "/usr/local/lib/python3.10/site-packages/django/http/request.py", line 152, in get_host
    raise DisallowedHost(msg)
django.core.exceptions.DisallowedHost: Invalid HTTP_HOST header: '111.231.22.116:8080'. You may need to add '111.231.22.116' to ALLOWED_HOSTS.
Invalid HTTP_HOST header: '111.231.22.116:8080'. You may need to add '111.231.22.116' to ALLOWED_HOSTS.
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/django/core/handlers/exception.py", line 56, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.10/site-packages/django/utils/deprecation.py", line 135, in __call__
    response = self.process_request(request)
  File "/usr/local/lib/python3.10/site-packages/django/middleware/common.py", line 48, in process_request
    host = request.get_host()
  File "/usr/local/lib/python3.10/site-packages/django/http/request.py", line 152, in get_host
    raise DisallowedHost(msg)
django.core.exceptions.DisallowedHost: Invalid HTTP_HOST header: '111.231.22.116:8080'. You may need to add '111.231.22.116' to ALLOWED_HOSTS.

“上面是报错的日志记录,这个报错是由于 Django 应用程序收到了一个无效的 HTTP_HOST 头部。HTTP_HOST 头部应该是访问网站的域名或 IP 地址,但在这种情况下,它包含了一个端口号(:8080),这是不正常的。这可能是因为请求被代理服务器发送到 Django 应用程序时,代理服务器将原始客户端的 IP 地址和端口添加到了 HTTP_HOST 头部中。”

以上是日志的一个解释,这个问题可能是在配置Nginx进行代理,或Shynet在不支持HTTPS的情况下,通过HTTPS协议访问后台管理页面导致的。

这个问题可以忽略,因为属于搭建环境中的报错,如果你的Shynet服务还不支持HTTPS,就先把配置文件修改过来,修改后就没有这个问题了。另外,我搭建服务后,没有用Nginx服务器进行代理,不知道有没有可能是这个原因?

总之,现在我的Shynet服务已经没有这个报错了。

4、执行ssl.webserver.sh 文件报错

这个问题在于前面没有配置 entrypoint.sh 文件,而是直接在Docker容器中执行ssl文件。

bash-5.1$ cat ssl.webserver.sh 
#!/bin/bash

# Start Gunicorn processes
echo Launching Shynet web server...
exec gunicorn shynet.wsgi:application \
    --bind 0.0.0.0:${PORT:-8080} \
    --workers ${NUM_WORKERS:-1} \
    --timeout 100 \
    --certfile=/usr/src/shynet/fangjunyu.com_bundle.pem \
    --keyfile=/usr/src/shynet/fangjunyu.com.keybash-5.1$ 
bash-5.1$ ./ssl.webserver.sh 
Launching Shynet web server...
[2024-04-03 15:36:58 +0000] [476] [INFO] Starting gunicorn 20.1.0
[2024-04-03 15:36:58 +0000] [476] [ERROR] Connection in use: ('0.0.0.0', 8080)
[2024-04-03 15:36:58 +0000] [476] [ERROR] Retrying in 1 second.
[2024-04-03 15:36:59 +0000] [476] [ERROR] Connection in use: ('0.0.0.0', 8080)
[2024-04-03 15:36:59 +0000] [476] [ERROR] Retrying in 1 second.
[2024-04-03 15:37:00 +0000] [476] [ERROR] Connection in use: ('0.0.0.0', 8080)

你成功的发现了配置ssl的文件,但是无法执行,这个问题其实很好理解,你可以直接通过查找所有正在运行的进程,并过滤出包含 “8080” 的进程信息。

bash-5.1$ ps -ef | grep 8080
    1 appuser   0:00 {gunicorn} /usr/local/bin/python /usr/local/bin/gunicorn shynet.wsgi:application --bind 0.0.0.0:8080 --workers 1 --timeout 100 --certfile=/usr/src/shynet/fangjunyu.com_bundle.pem --keyfile=/usr/src/shynet/fangjunyu.com.key
    9 appuser   0:11 {gunicorn} /usr/local/bin/python /usr/local/bin/gunicorn shynet.wsgi:application --bind 0.0.0.0:8080 --workers 1 --timeout 100 --certfile=/usr/src/shynet/fangjunyu.com_bundle.pem --keyfile=/usr/src/shynet/fangjunyu.com.key
  508 appuser   0:00 grep 8080

原因:存在两个 gunicorn 占用了8080端口,而且是在运行中。当你想要杀死这两个进程时,就是把主服务杀死,Dokcer也就会终止服务(如果你了解Docker容器运行的话),因此,你可能想,能不能修改这个 ssl.webserver.sh 文件内的端口?来解决端口被占用的问题,恭喜你,想错了。不能,因为你在创建容器时,设置的是通过服务器的8080端口来访问Docker的8080端口。如果你设置 ssl.webserver.sh 为8081端口,你的主服务是8080,端口服务还是跟着你的主服务来。

但是,你已经很接近了,你可能会想,我能不能让容器启动的时候,启用 ssl.webserver.sh,这时,只要你多了解一点Docker,你就会跟我一样,恍然大悟,明白只要修改 entrypoint.sh 文件就可以了。

因此,这个问题的解决方案还是配置 entrypoint.sh 文件。

5、Docker的文件都配置好后,系统还是无法登录

如果参照我的方法全部配置完成,系统仍然无法登录,请尝试使用

执行下面的命令重启服务

docker restart [容器名称 / 容器id]

然后通过

docker logs  [容器名称 / 容器id]

查看容器日志

Performing startup checks...
Database is ready to go.
Startup checks complete!
Launching Shynet web server...
[2024-04-03 14:58:26 +0000] [1] [INFO] Starting gunicorn 20.1.0
[2024-04-03 14:58:26 +0000] [1] [INFO] Listening at: https://0.0.0.0:8080 (1)
[2024-04-03 14:58:26 +0000] [1] [INFO] Using worker: sync
[2024-04-03 14:58:26 +0000] [9] [INFO] Booting worker with pid: 9
No hostname was supplied. Reverting to default 'localhost'

恭喜你,服务启动成功啦!!!完结撒花🎉🎉🎉

五、参考资料

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注