Compare commits
19
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2c3bd1426 | ||
|
|
2aeb327638 | ||
|
|
717b7569de | ||
|
|
2120009c8c | ||
|
|
5620f0051e | ||
|
|
f8e8fd1acd | ||
|
|
d1369d02d4 | ||
|
|
ebccfb4165 | ||
|
|
b9a35684ac | ||
|
|
7e6c95f78a | ||
|
|
54385d72ce | ||
|
|
2652213a10 | ||
|
|
4afb810078 | ||
|
|
3519fbe9e3 | ||
|
|
a08ca154c9 | ||
|
|
f92c3f52e0 | ||
|
|
22498cb884 | ||
|
|
8e550cba6b | ||
|
|
863d6ccc57 |
+220
-51
@@ -8,8 +8,8 @@ from PyQt5.QtWidgets import (
|
||||
QVBoxLayout, QHBoxLayout, QFrame, QMessageBox, QTextEdit,
|
||||
QCheckBox, QMenu, QDialog, QLineEdit,
|
||||
)
|
||||
from PyQt5.QtCore import Qt, QTimer, pyqtSignal
|
||||
from PyQt5.QtGui import QFont, QIcon, QPixmap, QImage, QColor
|
||||
from PyQt5.QtCore import Qt, QTimer, QRectF, pyqtSignal
|
||||
from PyQt5.QtGui import QFont, QIcon, QPixmap, QImage, QColor, QPainter
|
||||
|
||||
# GUI 窗口在 96 DPI / 100% 缩放下的逻辑尺寸;启用 Qt 高分屏缩放后,
|
||||
# Qt 会自动按 devicePixelRatio 放大/缩小,因此代码里保持逻辑尺寸不变即可。
|
||||
@@ -28,11 +28,12 @@ C_TEXT = "#333333" # 正文
|
||||
C_SUBTEXT = "#889099" # 次要文字
|
||||
|
||||
# ── 路径 ──────────────────────────────────────────────
|
||||
# frozen=True 表示已被 PyInstaller 打包为 EXE:
|
||||
# BASE_DIR -> EXE 解压出的临时目录(_MEIPASS)
|
||||
# 已被打包为 EXE(PyInstaller 的 sys.frozen / Nuitka 的 __compiled__):
|
||||
# BASE_DIR -> 内置数据目录:PyInstaller 用 _MEIPASS,Nuitka onefile 用
|
||||
# __file__ 所在解压临时目录(无 _MEIPASS 时回退)
|
||||
# PERSIST_DIR -> EXE 所在目录,服务安装等需要持久化的操作都放这里
|
||||
if getattr(sys, 'frozen', False):
|
||||
BASE_DIR = Path(sys._MEIPASS)
|
||||
if getattr(sys, 'frozen', False) or "__compiled__" in globals():
|
||||
BASE_DIR = Path(getattr(sys, "_MEIPASS", None) or Path(__file__).resolve().parent)
|
||||
PERSIST_DIR = Path(sys.executable).resolve().parent
|
||||
else:
|
||||
BASE_DIR = Path(__file__).resolve().parent
|
||||
@@ -88,6 +89,8 @@ def _load_nodes():
|
||||
if not isinstance(data, list):
|
||||
raise ValueError("nodes.json 顶层应为节点数组")
|
||||
_NODES = data
|
||||
if not _SELECTED_RESTORED:
|
||||
_restore_selected_node(_NODES) # 恢复上次使用的节点
|
||||
log(f"已加载节点配置: {len(_NODES)} 个 ({path})")
|
||||
if data and not str(data[0].get("domain") or "").strip():
|
||||
log_red("节点未填写域名:请配置 config.json 的 nodes_url 在线更新,"
|
||||
@@ -97,6 +100,7 @@ def _load_nodes():
|
||||
return _NODES
|
||||
|
||||
_SELECTED_NODE = 0 # 当前选中节点下标(默认第一条)
|
||||
_SELECTED_RESTORED = False # 启动时是否已按设置恢复过上次选中的节点
|
||||
|
||||
def _current_node():
|
||||
"""当前使用的节点:默认取列表第一个;无节点时返回 None。"""
|
||||
@@ -121,8 +125,26 @@ def _switch_node(index):
|
||||
log("已在当前节点")
|
||||
return False
|
||||
_SELECTED_NODE = index
|
||||
_save_current_node(nodes[index].get("domain") or "") # 记录到设置,下次启动恢复
|
||||
return True
|
||||
|
||||
def _restore_selected_node(nodes):
|
||||
"""首次加载时按设置里记录的 current_node(域名)恢复上次选中的节点。"""
|
||||
global _SELECTED_NODE, _SELECTED_RESTORED
|
||||
_SELECTED_RESTORED = True
|
||||
saved = str(_settings_load().get("current_node") or "")
|
||||
for i, n in enumerate(nodes):
|
||||
if saved and str(n.get("domain") or "") == saved:
|
||||
_SELECTED_NODE = i
|
||||
return
|
||||
_SELECTED_NODE = 0
|
||||
|
||||
def _save_current_node(domain):
|
||||
"""把当前选中节点域名写入设置文件(下次启动自动继续使用)。"""
|
||||
data = _settings_load()
|
||||
data["current_node"] = str(domain or "")
|
||||
_settings_save(data)
|
||||
|
||||
def _reload_nodes():
|
||||
"""强制重新读取 nodes.json(菜单打开时调用,外部改动即时生效)。"""
|
||||
global _NODES
|
||||
@@ -590,6 +612,47 @@ def _set_local_port(port):
|
||||
_settings_save(data)
|
||||
log(f"代理转发端口已保存: {port}(下次开启代理生效)")
|
||||
|
||||
def _update_via_proxy():
|
||||
"""更新检查/下载是否走节点隧道(CONNECT);设置项,默认关=直连仓库。"""
|
||||
return bool(_settings_load().get("update_via_proxy", False))
|
||||
|
||||
def _set_update_via_proxy(enabled):
|
||||
"""写回「使用代理更新」设置(立即生效)。"""
|
||||
data = _settings_load()
|
||||
data["update_via_proxy"] = bool(enabled)
|
||||
_settings_save(data)
|
||||
log(f"更新方式已设为: {'走代理隧道' if enabled else '直连仓库'}")
|
||||
|
||||
def _skip_update_check():
|
||||
"""是否跳过 PAC 数据与程序版本检查(设置项,默认关)。
|
||||
不影响节点配置更新与客户端认证。"""
|
||||
return bool(_settings_load().get("skip_update_check", False))
|
||||
|
||||
def _set_skip_update_check(enabled):
|
||||
"""写回「跳过检查更新」设置(立即生效)。"""
|
||||
data = _settings_load()
|
||||
data["skip_update_check"] = bool(enabled)
|
||||
_settings_save(data)
|
||||
log(f"检查更新已{'跳过' if enabled else '恢复'}(PAC 与程序版本;节点更新不受影响)")
|
||||
|
||||
def _ver_tuple(v):
|
||||
"""版本号转数字元组:'v0.1.0' -> (0, 1, 0),无法解析的段按 0 处理。"""
|
||||
parts = []
|
||||
for p in str(v).strip().lstrip("vV").split("."):
|
||||
try:
|
||||
parts.append(int(p))
|
||||
except ValueError:
|
||||
parts.append(0)
|
||||
return tuple(parts)
|
||||
|
||||
def _version_newer(latest, current):
|
||||
"""latest 是否比 current 新(逐段数字比较,位数不同补 0)。"""
|
||||
lt, ct = _ver_tuple(latest), _ver_tuple(current)
|
||||
n = max(len(lt), len(ct))
|
||||
lt += (0,) * (n - len(lt))
|
||||
ct += (0,) * (n - len(ct))
|
||||
return lt > ct
|
||||
|
||||
# 以下模块级取值需在 _data_path 定义之后执行
|
||||
VERSION = _config_val("version", "999908162319")
|
||||
_TLS_LOCAL_PORT = _port_val() # 本地转发器监听端口(设置 > 内置 config > 1080)
|
||||
@@ -792,6 +855,8 @@ def _user_init_remote(base_url=None):
|
||||
直接拉取两个数据文件(内含 version/date),按版本比对后更新;失败用本地副本。
|
||||
节点配置的拉取走登录框(nodes_url 需 nginx 认证,见 LoginDialog)。
|
||||
"""
|
||||
if _skip_update_check():
|
||||
return # 设置跳过:不拉取也不打日志
|
||||
base = (base_url or str(_config_val("pac_base_url", "") or "")).strip().rstrip("/")
|
||||
if not base:
|
||||
log("未配置 PAC 更新源(config.json 的 pac_base_url),使用本地数据")
|
||||
@@ -1372,7 +1437,7 @@ class SettingsDialog(QDialog):
|
||||
super().__init__(parent)
|
||||
self.setWindowTitle("设置")
|
||||
self.setWindowIcon(load_icon())
|
||||
self.setFixedSize(300, 230)
|
||||
self.setFixedSize(300, 316)
|
||||
self.setStyleSheet(f"""
|
||||
QDialog {{ background-color: {C_BG}; }}
|
||||
QLabel {{ color: {C_TEXT}; font-family: "Microsoft YaHei", "Segoe UI", sans-serif; font-size: 12px; }}
|
||||
@@ -1395,6 +1460,29 @@ class SettingsDialog(QDialog):
|
||||
title.setAlignment(Qt.AlignCenter)
|
||||
layout.addWidget(title)
|
||||
|
||||
# 版本号 + 手动「检查更新」入口(整体居中,中间隔小空)
|
||||
ver_row = QHBoxLayout()
|
||||
ver_row.addStretch()
|
||||
ver_lab = QLabel(f"版本号: {VERSION}")
|
||||
ver_lab.setStyleSheet(f"color: {C_SUBTEXT}; font-size: 11px;")
|
||||
ver_row.addWidget(ver_lab)
|
||||
ver_row.addSpacing(4)
|
||||
self.link_check_update = NodeLabel(
|
||||
"检查更新", tooltip="手动检查更新",
|
||||
base=f"color: {C_SUBTEXT}; font-size: 11px;",
|
||||
hover=f"color: {C_TEXT}; font-size: 11px; text-decoration: underline;")
|
||||
self.link_check_update.clicked.connect(self._manual_check_update)
|
||||
ver_row.addWidget(self.link_check_update)
|
||||
ver_row.addStretch()
|
||||
layout.addLayout(ver_row)
|
||||
|
||||
# 提示语:标题正下方(保存结果/错误也显示在这行)
|
||||
self.lb_hint = QLabel("代理运行中,关闭代理后可修改" if port_locked else "保存更改后下次开启代理生效")
|
||||
self.lb_hint.setStyleSheet(f"color: {C_SUBTEXT}; font-size: 11px;")
|
||||
self.lb_hint.setFixedHeight(14)
|
||||
self.lb_hint.setAlignment(Qt.AlignCenter)
|
||||
layout.addWidget(self.lb_hint)
|
||||
|
||||
layout.addStretch() # 设置项在空白部分纵向居中(上下均分)
|
||||
|
||||
# 代理转发端口
|
||||
@@ -1409,14 +1497,29 @@ class SettingsDialog(QDialog):
|
||||
port_row.addWidget(self.ed_port)
|
||||
layout.addLayout(port_row)
|
||||
|
||||
layout.addStretch()
|
||||
# 更新方式:左文字 + 右苹果式开关(默认关 = 直连仓库)
|
||||
upd_row = QHBoxLayout()
|
||||
upd_lab = QLabel("使用代理更新")
|
||||
upd_lab.setStyleSheet(f"color: {C_SUBTEXT}; font-size: 12px;")
|
||||
upd_row.addWidget(upd_lab)
|
||||
upd_row.addStretch()
|
||||
self.cb_update_proxy = ToggleSwitch(checked=_update_via_proxy())
|
||||
self.cb_update_proxy.setToolTip("开启后检查更新与下载走节点隧道(CONNECT);默认直连仓库")
|
||||
upd_row.addWidget(self.cb_update_proxy)
|
||||
layout.addLayout(upd_row)
|
||||
|
||||
# 提示语:按钮上方居中
|
||||
self.lb_hint = QLabel("代理运行中,关闭代理后可修改" if port_locked else "保存更改后下次开启代理生效")
|
||||
self.lb_hint.setStyleSheet(f"color: {C_SUBTEXT}; font-size: 11px;")
|
||||
self.lb_hint.setFixedHeight(14)
|
||||
self.lb_hint.setAlignment(Qt.AlignCenter)
|
||||
layout.addWidget(self.lb_hint)
|
||||
# 跳过检查更新:左文字 + 右开关(默认关;不影响节点更新与认证)
|
||||
skip_row = QHBoxLayout()
|
||||
skip_lab = QLabel("跳过检查更新")
|
||||
skip_lab.setStyleSheet(f"color: {C_SUBTEXT}; font-size: 12px;")
|
||||
skip_row.addWidget(skip_lab)
|
||||
skip_row.addStretch()
|
||||
self.cb_skip_update = ToggleSwitch(checked=_skip_update_check())
|
||||
self.cb_skip_update.setToolTip("跳过 PAC 数据与程序版本检查(节点更新与登录不受影响),被跳过的检查不输出日志")
|
||||
skip_row.addWidget(self.cb_skip_update)
|
||||
layout.addLayout(skip_row)
|
||||
|
||||
layout.addStretch()
|
||||
|
||||
# 底部:保存更改 + 退出登录 并排
|
||||
btns = QHBoxLayout()
|
||||
@@ -1449,6 +1552,27 @@ class SettingsDialog(QDialog):
|
||||
btns.addStretch()
|
||||
layout.addLayout(btns)
|
||||
|
||||
def _manual_check_update(self):
|
||||
"""手动触发一次检查更新(后台线程,复用主窗口逻辑)。"""
|
||||
parent = self.parent()
|
||||
if not isinstance(parent, MainWindow):
|
||||
return
|
||||
self.lb_hint.setText("正在检查更新...")
|
||||
self.lb_hint.setStyleSheet(f"color: {C_SUBTEXT}; font-size: 11px;")
|
||||
try:
|
||||
parent._update_done.connect(self._on_check_done)
|
||||
except TypeError:
|
||||
pass # 已连接过,忽略
|
||||
threading.Thread(target=parent._check_update, kwargs={"manual": True}, daemon=True).start()
|
||||
|
||||
def _on_check_done(self):
|
||||
self.lb_hint.setText("检查完成,结果见主界面日志")
|
||||
self.lb_hint.setStyleSheet(f"color: {C_SUBTEXT}; font-size: 11px;")
|
||||
try:
|
||||
self.parent()._update_done.disconnect(self._on_check_done)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _save_settings(self):
|
||||
"""保存更改:统一校验并应用全部设置项(后续新增设置项在此扩展)。"""
|
||||
port = _parse_port(self.ed_port.text())
|
||||
@@ -1457,8 +1581,10 @@ class SettingsDialog(QDialog):
|
||||
self.lb_hint.setStyleSheet(f"color: {C_RED}; font-size: 11px;")
|
||||
return
|
||||
_set_local_port(port)
|
||||
_set_update_via_proxy(bool(self.cb_update_proxy.isChecked()))
|
||||
_set_skip_update_check(bool(self.cb_skip_update.isChecked()))
|
||||
self.ed_port.setText(str(port))
|
||||
self.lb_hint.setText(f"已保存: {port},下次开启代理生效")
|
||||
self.lb_hint.setText("已保存,下次开启代理生效")
|
||||
self.lb_hint.setStyleSheet(f"color: {C_GREEN}; font-size: 11px;")
|
||||
|
||||
def _logout(self):
|
||||
@@ -1473,6 +1599,39 @@ class SettingsDialog(QDialog):
|
||||
log("已退出登录:凭据与节点配置已清除,下次启动或开启代理时需重新登录")
|
||||
self.accept()
|
||||
|
||||
# ── 苹果风格开关 ─────────────────────────────────────
|
||||
|
||||
class ToggleSwitch(QCheckBox):
|
||||
"""苹果风格开关:左关右开,绿/灰胶囊 + 滑动圆钮(自绘,无图片资源)。"""
|
||||
|
||||
def __init__(self, checked=False, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setChecked(checked)
|
||||
self.setFixedSize(42, 22)
|
||||
self.setCursor(Qt.PointingHandCursor)
|
||||
|
||||
def paintEvent(self, e):
|
||||
p = QPainter(self)
|
||||
p.setRenderHint(QPainter.Antialiasing)
|
||||
p.setPen(Qt.NoPen)
|
||||
# 胶囊背景:开=主题绿,关=浅灰
|
||||
p.setBrush(QColor(C_GREEN) if self.isChecked() else QColor("#c8ccd4"))
|
||||
p.drawRoundedRect(QRectF(0, 0, 42, 22), 11, 11)
|
||||
# 白色圆钮:开在右,关在左
|
||||
knob_x = 20.0 if self.isChecked() else 2.0
|
||||
p.setBrush(QColor("#ffffff"))
|
||||
p.drawEllipse(QRectF(knob_x, 2.0, 18.0, 18.0))
|
||||
p.end()
|
||||
|
||||
def mousePressEvent(self, e):
|
||||
# 显式处理点击切换:自绘控件在部分样式引擎下默认点击不触发
|
||||
if e.button() == Qt.LeftButton:
|
||||
self.setChecked(not self.isChecked())
|
||||
self.repaint()
|
||||
e.accept()
|
||||
return
|
||||
super().mousePressEvent(e)
|
||||
|
||||
# ── 状态指示灯(小圆点) ───────────────────────────────
|
||||
|
||||
class StatusDot(QLabel):
|
||||
@@ -2008,41 +2167,44 @@ class MainWindow(QWidget):
|
||||
self.traffic_up.setText(f"↑{_fmt_bytes(up_rate)}/s")
|
||||
self.traffic_down.setText(f"↓{_fmt_bytes(down_rate)}/s")
|
||||
self.traffic_total.setText(_fmt_bytes(up_total + down_total))
|
||||
def _check_update(self):
|
||||
"""后台检查服务器是否有新版本。"""
|
||||
def _check_update(self, manual=False):
|
||||
"""后台检查服务器是否有新版本;manual=True 时无视「跳过检查更新」设置。"""
|
||||
# 先初始化结果,任何路径(含跳过)完成后 _on_update_done 都能安全读取
|
||||
self._latest_version = ""
|
||||
self._download_url = ""
|
||||
try:
|
||||
import json, urllib.request, base64
|
||||
domain = _endpoint_domain()
|
||||
if domain == "???":
|
||||
log("更新检查: 未配置节点(nodes.json 域名为空),跳过")
|
||||
return
|
||||
# 更新链接优先取 config.json 的 update_url,缺失时回退到域名拼接
|
||||
url = _config_val("update_url", "")
|
||||
if _skip_update_check() and not manual:
|
||||
return # 设置跳过(仅自动检查):不检查也不打日志
|
||||
import json, urllib.request
|
||||
# 基于 Gitea 仓库 releases API 检查更新;config.json 无 update_url 时用默认地址
|
||||
url = str(_config_val("update_url", "") or "").strip()
|
||||
if not url:
|
||||
url = f"https://{domain}/latest_version.json"
|
||||
url = ("https://git.bu4.ren/api/v1/repos/RoyirinRosmontis/"
|
||||
"Private-Proxy/releases/latest")
|
||||
log("正在检查更新...")
|
||||
# 显式走本地转发器隧道,不依赖系统代理状态:默认 opener 读注册表代理设置
|
||||
# (异常退出残留 127.0.0.1 代理 -> 连接被拒),不识别 PAC 的 AutoConfigURL,
|
||||
# 直连服务器还可能被墙干扰 TLS 握手(SSL UNEXPECTED_EOF)
|
||||
started_here = _ensure_forwarder()
|
||||
try:
|
||||
opener = urllib.request.build_opener(urllib.request.ProxyHandler(
|
||||
{"http": f"{PROXY_HOST}:{PROXY_PORT}",
|
||||
"https": f"{PROXY_HOST}:{PROXY_PORT}"}))
|
||||
if _update_via_proxy():
|
||||
# 走节点隧道(CONNECT,设置「使用代理更新」开启时);显式代理避免残留干扰
|
||||
started_here = _ensure_forwarder()
|
||||
try:
|
||||
opener = urllib.request.build_opener(urllib.request.ProxyHandler(
|
||||
{"http": f"{PROXY_HOST}:{PROXY_PORT}",
|
||||
"https": f"{PROXY_HOST}:{PROXY_PORT}"}))
|
||||
req = urllib.request.Request(url)
|
||||
data = opener.open(req, timeout=20).read().decode("utf-8-sig")
|
||||
finally:
|
||||
_release_forwarder(started_here)
|
||||
else:
|
||||
# 默认直连仓库;显式空代理避免系统/环境残留代理干扰
|
||||
opener = _pac_no_proxy_opener()
|
||||
req = urllib.request.Request(url)
|
||||
data = opener.open(req, timeout=10).read().decode("utf-8-sig")
|
||||
finally:
|
||||
_release_forwarder(started_here)
|
||||
data = opener.open(req, timeout=20).read().decode("utf-8-sig")
|
||||
info = json.loads(data)
|
||||
log("客户端认证成功")
|
||||
self._latest_version = info.get("latest_version", "")
|
||||
self._download_url = info.get("download_url", "")
|
||||
log(f"当前版本: {VERSION},最新版本: {self._latest_version}")
|
||||
if VERSION.startswith("9999"):
|
||||
log("您当前正在使用 Lite 版")
|
||||
# 基于 Gitea 仓库 releases API:版本取 tag_name,下载取 exe 附件链接
|
||||
self._latest_version = str(info.get("tag_name") or "")
|
||||
assets = info.get("assets") or []
|
||||
self._download_url = (assets[0].get("browser_download_url") or ""
|
||||
if assets else "")
|
||||
log(f"当前版本: {VERSION},最新版本: {self._latest_version or '未知'}")
|
||||
except Exception as e:
|
||||
log(f"更新检查失败: {e}")
|
||||
self._latest_version = ""
|
||||
@@ -2053,7 +2215,7 @@ class MainWindow(QWidget):
|
||||
def _on_update_done(self):
|
||||
"""更新检查完成后恢复按钮;发现新版本时弹窗询问是否下载。"""
|
||||
self.btn_toggle.setEnabled(True)
|
||||
if self._latest_version and self._latest_version > VERSION:
|
||||
if self._latest_version and _version_newer(self._latest_version, VERSION):
|
||||
reply = QMessageBox.question(
|
||||
self, "发现新版本",
|
||||
f"当前版本: {VERSION}\n最新版本: {self._latest_version}\n\n是否下载更新?",
|
||||
@@ -2078,18 +2240,25 @@ class MainWindow(QWidget):
|
||||
log(f"正在下载新版本: {url}")
|
||||
log(f"保存到: {save_path}")
|
||||
|
||||
# 同更新检查:显式走本地转发器隧道,不依赖系统代理状态
|
||||
started_here = _ensure_forwarder()
|
||||
try:
|
||||
opener = urllib.request.build_opener(urllib.request.ProxyHandler(
|
||||
{"http": f"{PROXY_HOST}:{PROXY_PORT}",
|
||||
"https": f"{PROXY_HOST}:{PROXY_PORT}"}))
|
||||
# 同更新检查:按「使用代理更新」设置选择隧道或直连
|
||||
if _update_via_proxy():
|
||||
started_here = _ensure_forwarder()
|
||||
try:
|
||||
opener = urllib.request.build_opener(urllib.request.ProxyHandler(
|
||||
{"http": f"{PROXY_HOST}:{PROXY_PORT}",
|
||||
"https": f"{PROXY_HOST}:{PROXY_PORT}"}))
|
||||
req = urllib.request.Request(url)
|
||||
|
||||
with opener.open(req, timeout=120) as resp:
|
||||
data = resp.read()
|
||||
finally:
|
||||
_release_forwarder(started_here)
|
||||
else:
|
||||
opener = _pac_no_proxy_opener()
|
||||
req = urllib.request.Request(url)
|
||||
|
||||
with opener.open(req, timeout=120) as resp:
|
||||
data = resp.read()
|
||||
finally:
|
||||
_release_forwarder(started_here)
|
||||
|
||||
if len(data) < 1024:
|
||||
self._update_download_done.emit(False, "下载文件过小,可能不是有效的 EXE")
|
||||
|
||||
@@ -56,15 +56,14 @@ http {
|
||||
}
|
||||
}
|
||||
|
||||
# 443 端口:iam.aeolianchi.me HTTPS 站点 + 认证 CONNECT 代理
|
||||
server {
|
||||
listen 443 ssl;
|
||||
http2 on;
|
||||
server_name iam.aeolianchi.me;
|
||||
server_name XXX;
|
||||
root /var/www/html;
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/iam.aeolianchi.me/fullchain.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/iam.aeolianchi.me/privkey.pem;
|
||||
ssl_certificate /etc/nginx/ssl/XXX/fullchain.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/XXX/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
|
||||
Reference in New Issue
Block a user