Ubuntu+Apache(mod_wsgi)+Django下requests.post连接被拒问题求助
问题排查:Django部署后内部requests调用API连接被拒
环境
- Ubuntu 24.04
- Apache 2.4(搭配libapache2-mod-wsgi-py3 5.0.0-1build2)
- Python 3.12(搭配requests 2.32.3)
- Django Admin 5.1.6
问题描述
Django项目通过Apache(mod_wsgi)部署后,浏览器访问https://mysub.mydom.com/myapp和https://mysub.mydom.com/myapp/api/v1/endpoint均正常返回200,但代码中使用requests.post调用该API端点时,出现以下错误:
HTTPSConnectionPool(host='mysub.mydom.com', port=443): Max retries exceeded with url: /myapp/api/v1/endpoint (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7191eb589e50>: Failed to establish a new connection: [Errno 111] Connection refused'))
ufw已启用“Apache Full”规则,相关配置如下,需排查连接被拒的原因。
Apache站点配置(mysub.mydom.com.conf)
Define wsgi_daemon "mydjango_proc" <VirtualHost *:80> ServerName mysub.mydom.com ServerAdmin webmaster@mydom.com DocumentRoot /home/myuser/my_django/my_project <IfModule mpm_itk_module> AssignUserId myuser www-data </IfModule> ErrorLog /home/myuser/my_django/log/my_project.error.log CustomLog /home/myuser/my_django/log/my_project.access.log common Alias /static /home/myuser/my_django/my_project/static <Directory /home/myuser/my_django/my_project/static> Require all granted </Directory> <Directory /home/myuser/my_django/my_project/my_project> <Files wsgi.py> Require all granted </Files> </Directory> <Directory /home/myuser/my_django/my_project> Require all granted </Directory> <IfDefine !wsgi_init> WSGIApplicationGroup %{GLOBAL} WSGIProcessGroup %{GLOBAL} WSGIDaemonProcess ${wsgi_daemon} python-home=/home/myuser/my_django/sklp_env python-path=/home/myuser/my_django/my_project user=myuser socket-user=myuser WSGIProcessGroup ${wsgi_daemon} WSGIScriptAlias / /home/myuser/my_django/my_project/my_project/wsgi.py Define wsgi_init 1 </IfDefine> </VirtualHost>
Django项目结构
home |-- myuser |-- my_django (group: www-data) |-- sklp_env `-- my_project (group: www-data) |-- myapp |-- my_project |-- static |-- db.sqlite3 (group: www-data / permission: 664) `-- manage.py
settings.py相关配置
... ALLOWED_HOSTS = ['xxx.xxx.xxx.xxx','mysub.mydom.com'] SECURE_HSTS_SECONDS = 60 SECURE_HSTS_INCLUDE_SUBDOMAINS = True SECURE_HSTS_PRELOAD = True SECURE_SSL_REDIRECT = True SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True ...
排查方向与解决方案
1. Apache HTTPS配置缺失
当前Apache配置仅包含*:80的VirtualHost,无HTTPS(443端口)站点配置。浏览器能访问HTTPS可能是通过反向代理或Certbot自动配置,但服务器内部请求可能无法识别443端口的监听:
- 执行
apache2ctl -S查看所有站点配置,确认mysub.mydom.com有对应的*:443配置。 - 若缺失,需补充HTTPS站点配置,包含SSL证书及与80端口一致的WSGI设置,重启Apache生效。
2. 服务器内部域名解析异常
代码调用mysub.mydom.com时,服务器内部可能未将域名解析到本地IP:
- 在服务器执行
ping mysub.mydom.com,检查返回IP是否为服务器本地IP(xxx.xxx.xxx.xxx)。 - 若解析错误,修改
/etc/hosts添加一行xxx.xxx.xxx.xxx mysub.mydom.com,强制本地解析到正确IP。
3. 443端口未被监听或防火墙拦截
尽管ufw允许Apache Full,仍可能存在端口未监听或内部规则拦截:
- 执行
netstat -tulpn | grep :443,确认apache2进程是否监听443端口。 - 若未监听,启用Apache SSL模块:
a2enmod ssl,然后重启Apache:systemctl restart apache2。
4. 内部调用替代方案(规避网络请求)
若为Django内部调用自身API,无需走外部HTTPS,直接调用视图或使用Django测试客户端更高效:
from django.test import Client client = Client() response = client.post('/myapp/api/v1/endpoint', data=your_request_data) # 处理返回的response对象
内容的提问来源于stack exchange,提问作者sariDon
相关产品推荐
相关产品推荐

