mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-10-06 13:27:43 +08:00
feat: Add HTTPS fallback prevention configuration in OpenResty (#9703)
This commit is contained in:
parent
04b9cbd87a
commit
0316cb0662
18 changed files with 277 additions and 0 deletions
|
@ -157,3 +157,39 @@ func (b *BaseApi) GetNginxModules(c *gin.Context) {
|
|||
}
|
||||
helper.SuccessWithData(c, modules)
|
||||
}
|
||||
|
||||
// @Tags OpenResty
|
||||
// @Summary Operate default HTTPs
|
||||
// @Accept json
|
||||
// @Param request body request.NginxOperateReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /openresty/https [post]
|
||||
func (b *BaseApi) OperateDefaultHTTPs(c *gin.Context) {
|
||||
var req request.NginxOperateReq
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := nginxService.OperateDefaultHTTPs(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags OpenResty
|
||||
// @Summary Get default HTTPs status
|
||||
// @Success 200 {object} response.NginxConfigRes
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /openresty/https [get]
|
||||
func (b *BaseApi) GetDefaultHTTPsStatus(c *gin.Context) {
|
||||
res, err := nginxService.GetDefaultHttpsStatus()
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
|
|
@ -126,3 +126,7 @@ type NginxModuleUpdate struct {
|
|||
Enable bool `json:"enable"`
|
||||
Params string `json:"params"`
|
||||
}
|
||||
|
||||
type NginxOperateReq struct {
|
||||
Operate string `json:"operate" validate:"required,oneof=enable disable"`
|
||||
}
|
||||
|
|
|
@ -80,3 +80,7 @@ type NginxBuildConfig struct {
|
|||
Mirror string `json:"mirror"`
|
||||
Modules []NginxModule `json:"modules"`
|
||||
}
|
||||
|
||||
type NginxConfigRes struct {
|
||||
Https bool `json:"https"`
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/nginx"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/nginx/parser"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
|
@ -42,6 +44,9 @@ type INginxService interface {
|
|||
Build(req request.NginxBuildReq) error
|
||||
GetModules() (*response.NginxBuildConfig, error)
|
||||
UpdateModule(req request.NginxModuleUpdate) error
|
||||
|
||||
OperateDefaultHTTPs(req request.NginxOperateReq) error
|
||||
GetDefaultHttpsStatus() (*response.NginxConfigRes, error)
|
||||
}
|
||||
|
||||
func NewINginxService() INginxService {
|
||||
|
@ -348,3 +353,70 @@ func (n NginxService) UpdateModule(req request.NginxModuleUpdate) error {
|
|||
}
|
||||
return fileOp.SaveFileWithByte(moduleConfigPath, moduleByte, constant.DirPerm)
|
||||
}
|
||||
|
||||
func (n NginxService) OperateDefaultHTTPs(req request.NginxOperateReq) error {
|
||||
appInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
websites, _ := websiteRepo.List()
|
||||
hasDefaultWebsite := false
|
||||
for _, website := range websites {
|
||||
if website.DefaultServer {
|
||||
hasDefaultWebsite = true
|
||||
break
|
||||
}
|
||||
}
|
||||
defaultConfigPath := path.Join(appInstall.GetPath(), "conf", "default", "00.default.conf")
|
||||
content, err := os.ReadFile(defaultConfigPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if req.Operate == "enable" {
|
||||
if err := handleSSLConfig(&appInstall, hasDefaultWebsite); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if req.Operate == "disable" {
|
||||
defaultConfig, err := parser.NewStringParser(string(content)).Parse()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defaultConfig.FilePath = defaultConfigPath
|
||||
defaultServer := defaultConfig.FindServers()[0]
|
||||
defaultServer.RemoveListen(fmt.Sprintf("%d", appInstall.HttpsPort))
|
||||
defaultServer.RemoveListen(fmt.Sprintf("[::]:%d", appInstall.HttpsPort))
|
||||
defaultServer.RemoveDirective("include", []string{"/usr/local/openresty/nginx/conf/ssl/root_ssl.conf"})
|
||||
defaultServer.RemoveDirective("http2", []string{"on"})
|
||||
if err = nginx.WriteConfig(defaultConfig, nginx.IndentedStyle); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nginxCheckAndReload(string(content), defaultConfigPath, appInstall.ContainerName)
|
||||
}
|
||||
|
||||
func (n NginxService) GetDefaultHttpsStatus() (*response.NginxConfigRes, error) {
|
||||
appInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defaultConfigPath := path.Join(appInstall.GetPath(), "conf", "default", "00.default.conf")
|
||||
content, err := os.ReadFile(defaultConfigPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defaultConfig, err := parser.NewStringParser(string(content)).Parse()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defaultConfig.FilePath = defaultConfigPath
|
||||
defaultServer := defaultConfig.FindServers()[0]
|
||||
res := &response.NginxConfigRes{}
|
||||
for _, directive := range defaultServer.GetDirectives() {
|
||||
if directive.GetName() == "include" && directive.GetParameters()[0] == "/usr/local/openresty/nginx/conf/ssl/root_ssl.conf" {
|
||||
return &response.NginxConfigRes{
|
||||
Https: true,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
|
|
@ -21,5 +21,7 @@ func (a *NginxRouter) InitRouter(Router *gin.RouterGroup) {
|
|||
groupRouter.POST("/build", baseApi.BuildNginx)
|
||||
groupRouter.POST("/modules/update", baseApi.UpdateNginxModule)
|
||||
groupRouter.GET("/modules", baseApi.GetNginxModules)
|
||||
groupRouter.POST("/https", baseApi.OperateDefaultHTTPs)
|
||||
groupRouter.GET("/https", baseApi.GetDefaultHTTPsStatus)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,4 +50,12 @@ export namespace Nginx {
|
|||
export interface NginxModuleUpdate extends NginxModule {
|
||||
operate: string;
|
||||
}
|
||||
|
||||
export interface NginxHttpsStatus {
|
||||
https: boolean;
|
||||
}
|
||||
|
||||
export interface NginxOperateReq {
|
||||
operate: string;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,3 +33,11 @@ export const getNginxModules = () => {
|
|||
export const updateNginxModule = (req: Nginx.NginxModuleUpdate) => {
|
||||
return http.post(`/openresty/modules/update`, req);
|
||||
};
|
||||
|
||||
export const getHttpsStatus = () => {
|
||||
return http.get<Nginx.NginxHttpsStatus>(`/openresty/https`);
|
||||
};
|
||||
|
||||
export const operateHttps = (req: Nginx.NginxOperateReq) => {
|
||||
return http.post(`/openresty/https`, req);
|
||||
};
|
||||
|
|
|
@ -2566,6 +2566,8 @@ const message = {
|
|||
'Scripts to execute before compilation, usually for downloading module source code, installing dependencies, etc.',
|
||||
buildHelper:
|
||||
'Click build after adding/modifying a module. OpenResty will automatically restart upon successful build.',
|
||||
defaultHttps: 'HTTPS Anti-tampering',
|
||||
defaultHttpsHelper1: 'Enabling this can resolve HTTPS tampering issues.',
|
||||
},
|
||||
ssl: {
|
||||
create: 'Request',
|
||||
|
|
|
@ -2466,6 +2466,24 @@ const message = {
|
|||
clearProxyCache: '逆プロキシキャッシュをきれいにします',
|
||||
clearProxyCacheWarn:
|
||||
'キャッシュで構成されたすべてのWebサイトが影響を受け、「OpenResty」が再起動されます。続けたいですか?',
|
||||
create: 'モジュールを追加',
|
||||
update: 'モジュールを編集',
|
||||
params: 'パラメータ',
|
||||
packages: 'パッケージ',
|
||||
script: 'スクリプト',
|
||||
module: 'モジュール',
|
||||
build: 'ビルド',
|
||||
buildWarn:
|
||||
'OpenRestyのビルドには一定量のCPUとメモリを確保する必要があり、時間がかかる場合がありますので、お待ちください。',
|
||||
mirrorUrl: 'ソフトウェアソース',
|
||||
paramsHelper: '例:--add-module=/tmp/ngx_brotli',
|
||||
packagesHelper: '例:git,curl カンマ区切り',
|
||||
scriptHelper:
|
||||
'コンパイル前に実行するスクリプト、通常はモジュールソースコードのダウンロード、依存関係のインストールなど',
|
||||
buildHelper:
|
||||
'モジュールの追加/変更後にビルドをクリックします。ビルドが成功すると、OpenRestyは自動的に再起動します。',
|
||||
defaultHttps: 'HTTPS 改ざん防止',
|
||||
defaultHttpsHelper1: 'これを有効にすると、HTTPS 改ざん問題を解決できます。',
|
||||
},
|
||||
ssl: {
|
||||
create: 'リクエスト',
|
||||
|
|
|
@ -2423,6 +2423,21 @@ const message = {
|
|||
clearProxyCache: '리버스 프록시 캐시 삭제',
|
||||
clearProxyCacheWarn:
|
||||
'캐시가 구성된 모든 웹사이트에 영향을 미치며 OpenResty 가 다시 시작됩니다. 계속하시겠습니까?',
|
||||
create: '모듈 추가',
|
||||
update: '모듈 편집',
|
||||
params: '매개변수',
|
||||
packages: '패키지',
|
||||
script: '스크립트',
|
||||
module: '모듈',
|
||||
build: '빌드',
|
||||
buildWarn: 'OpenResty 빌드는 CPU와 메모리의 일정량을 예약해야 하며, 시간이 오래 걸릴 수 있으니 기다려 주세요.',
|
||||
mirrorUrl: '소프트웨어 소스',
|
||||
paramsHelper: '예: --add-module=/tmp/ngx_brotli',
|
||||
packagesHelper: '예: git,curl 쉼표로 구분',
|
||||
scriptHelper: '컴파일 전에 실행할 스크립트, 일반적으로 모듈 소스 코드 다운로드, 종속성 설치 등',
|
||||
buildHelper: '모듈 추가/수정 후 빌드를 클릭하세요. 빌드가 성공하면 OpenResty가 자동으로 재시작됩니다.',
|
||||
defaultHttps: 'HTTPS 변조 방지',
|
||||
defaultHttpsHelper1: '이를 활성화하면 HTTPS 변조 문제를 해결할 수 있습니다.',
|
||||
},
|
||||
ssl: {
|
||||
create: '요청',
|
||||
|
|
|
@ -2522,6 +2522,24 @@ const message = {
|
|||
clearProxyCache: 'Bersihkan cache proksi terbalik',
|
||||
clearProxyCacheWarn:
|
||||
'Semua laman web yang dikonfigurasi dengan cache akan terjejas dan "OpenResty" akan dimulakan semula. Adakah anda mahu meneruskan?',
|
||||
create: 'Tambah Modul',
|
||||
update: 'Edit Modul',
|
||||
params: 'Parameter',
|
||||
packages: 'Pakej',
|
||||
script: 'Script',
|
||||
module: 'Modul',
|
||||
build: 'Bina',
|
||||
buildWarn:
|
||||
'Membina OpenResty memerlukan menyediakan sejumlah CPU dan memori, dan prosesnya mengambil masa yang lama, sila bersabar.',
|
||||
mirrorUrl: 'Sumber Perisian',
|
||||
paramsHelper: 'Contoh: --add-module=/tmp/ngx_brotli',
|
||||
packagesHelper: 'Contoh: git,curl dipisahkan oleh koma',
|
||||
scriptHelper:
|
||||
'Skrip yang dilaksanakan sebelum penyusunan, biasanya untuk memuat turun sumber kod modul, memasang kebergantungan, dll.',
|
||||
buildHelper:
|
||||
'Klik Bina selepas menambah/mengubah suai modul. Pembinaan yang berjaya akan memulakan semula OpenResty secara automatik.',
|
||||
defaultHttps: 'HTTPS Anti-tampering',
|
||||
defaultHttpsHelper1: 'Mengaktifkan ini dapat menyelesaikan masalah tampering HTTPS.',
|
||||
},
|
||||
ssl: {
|
||||
create: 'Permintaan',
|
||||
|
|
|
@ -2523,6 +2523,24 @@ const message = {
|
|||
clearProxyCache: 'Clean reverse proxy cache',
|
||||
clearProxyCacheWarn:
|
||||
'All websites that have configured with cache will be affected and "OpenResty" will be restarted. Do you want to continue?',
|
||||
create: 'Criar Módulo',
|
||||
update: 'Editar Módulo',
|
||||
params: 'Parâmetros',
|
||||
packages: 'Pacotes',
|
||||
script: 'Script',
|
||||
module: 'Módulo',
|
||||
build: 'Construir',
|
||||
buildWarn:
|
||||
'Construir OpenResty requer a reserva de certa quantidade de CPU e memória, e o processo pode ser demorado, por favor, seja paciente.',
|
||||
mirrorUrl: 'Fonte de Software',
|
||||
paramsHelper: 'Por exemplo: --add-module=/tmp/ngx_brotli',
|
||||
packagesHelper: 'Por exemplo: git,curl separados por vírgulas',
|
||||
scriptHelper:
|
||||
'Script a ser executado antes da compilação, geralmente para baixar o código-fonte do módulo, instalar dependências, etc.',
|
||||
buildHelper:
|
||||
'Clique em Construir após adicionar/modificar um módulo. Construção bem-sucedida reiniciará automaticamente o OpenResty.',
|
||||
defaultHttps: 'HTTPS Anti-tampering',
|
||||
defaultHttpsHelper1: 'A ativação desta opção pode resolver problemas de adulteração HTTPS.',
|
||||
},
|
||||
ssl: {
|
||||
create: 'Solicitar',
|
||||
|
|
|
@ -2519,6 +2519,24 @@ const message = {
|
|||
clearProxyCache: 'Очистить кэш обратного прокси',
|
||||
clearProxyCacheWarn:
|
||||
'Это повлияет на все веб-сайты с настроенным кэшем и перезапустит "OpenResty". Хотите продолжить?',
|
||||
create: 'Создать модуль',
|
||||
update: 'Редактировать модуль',
|
||||
params: 'Параметры',
|
||||
packages: 'Пакеты',
|
||||
script: 'Скрипт',
|
||||
module: 'Модуль',
|
||||
build: 'Сборка',
|
||||
buildWarn:
|
||||
'Сборка OpenResty требует резервирования определенного количества CPU и памяти, процесс может занять много времени, пожалуйста, подождите.',
|
||||
mirrorUrl: 'Источник программного обеспечения',
|
||||
paramsHelper: 'Например: --add-module=/tmp/ngx_brotli',
|
||||
packagesHelper: 'Например: git,curl разделенные запятыми',
|
||||
scriptHelper:
|
||||
'Скрипт, выполняемый перед компиляцией, обычно для загрузки исходного кода модуля, установки зависимостей и т.д.',
|
||||
buildHelper:
|
||||
'Нажмите Сборка после добавления/изменения модуля. Успешная сборка автоматически перезапустит OpenResty.',
|
||||
defaultHttps: 'HTTPS Анти-вмешательство',
|
||||
defaultHttpsHelper1: 'Включение этого параметра может решить проблему вмешательства в HTTPS.',
|
||||
},
|
||||
ssl: {
|
||||
create: 'Запросить',
|
||||
|
|
|
@ -2597,6 +2597,8 @@ const message = {
|
|||
'Derlemeden önce çalıştırılacak betikler, genellikle modül kaynak kodunu indirmek, bağımlılıkları kurmak vb. için',
|
||||
buildHelper:
|
||||
'Modül ekledikten/düzenledikten sonra oluştur’a tıklayın. OpenResty, başarılı oluşturma üzerine otomatik olarak yeniden başlatılacaktır.',
|
||||
defaultHttps: 'HTTPS Anti-sızdırma',
|
||||
defaultHttpsHelper1: 'Bu özelliği etkinleştirerek HTTPS sızdırma sorunlarını çözebilirsiniz.',
|
||||
},
|
||||
ssl: {
|
||||
create: 'İstek',
|
||||
|
|
|
@ -2395,6 +2395,8 @@ const message = {
|
|||
packagesHelper: '例如:git,curl 以逗號分割',
|
||||
scriptHelper: '編譯之前執行的腳本,通常用於下載模組原始碼,安裝依賴等',
|
||||
buildHelper: '添加/修改模組後點擊構建,構建成功後會自動重啟 OpenResty',
|
||||
defaultHttps: 'HTTPS 防竄站',
|
||||
defaultHttpsHelper1: '開啟後可以解決 HTTPS 竄站問題',
|
||||
},
|
||||
ssl: {
|
||||
create: '申請證書',
|
||||
|
|
|
@ -2384,6 +2384,8 @@ const message = {
|
|||
packagesHelper: '例如:git,curl 按,分割',
|
||||
scriptHelper: '编译之前执行的脚本,一般为下载模块源码,安装依赖等',
|
||||
buildHelper: '添加/修改模块之后点击构建,构建成功后会自动重启 OpenResty',
|
||||
defaultHttps: 'HTTPS 防窜站',
|
||||
defaultHttpsHelper1: '开启后可以解决 HTTPS 窜站问题',
|
||||
},
|
||||
ssl: {
|
||||
create: '申请证书',
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
<el-button type="primary" :plain="activeName !== '5'" @click="changeTab('5')">
|
||||
{{ $t('runtime.module') }}
|
||||
</el-button>
|
||||
<el-button type="primary" :plain="activeName !== '6'" @click="changeTab('6')">
|
||||
{{ $t('website.other') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<template #main>
|
||||
<Status v-if="activeName === '1'" :status="status" />
|
||||
|
@ -33,6 +36,7 @@
|
|||
<NginxPer v-if="activeName === '3'" />
|
||||
<ContainerLog v-if="activeName === '4'" :container="containerName" :highlightDiff="350" />
|
||||
<Module v-if="activeName === '5'" />
|
||||
<Other v-if="activeName === '6'" />
|
||||
</template>
|
||||
</LayoutContent>
|
||||
</template>
|
||||
|
@ -44,6 +48,7 @@ import ContainerLog from '@/components/log/container/index.vue';
|
|||
import NginxPer from './performance/index.vue';
|
||||
import Status from './status/index.vue';
|
||||
import Module from './module/index.vue';
|
||||
import Other from './other/index.vue';
|
||||
|
||||
const activeName = ref('1');
|
||||
|
||||
|
|
43
frontend/src/views/website/website/nginx/other/index.vue
Normal file
43
frontend/src/views/website/website/nginx/other/index.vue
Normal file
|
@ -0,0 +1,43 @@
|
|||
<template>
|
||||
<div v-if="showPage" v-loading="loading">
|
||||
<el-text>{{ $t('nginx.defaultHttps') }}</el-text>
|
||||
<el-switch class="ml-2" v-model="enable" @change="changeStatus"></el-switch>
|
||||
<div>
|
||||
<el-text type="info" size="small">{{ $t('nginx.defaultHttpsHelper1') }}</el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { getHttpsStatus, operateHttps } from '@/api/modules/nginx';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
|
||||
const showPage = ref(false);
|
||||
const enable = ref(false);
|
||||
const loading = ref(false);
|
||||
|
||||
const getStatus = async () => {
|
||||
try {
|
||||
const res = await getHttpsStatus();
|
||||
enable.value = res.data.https;
|
||||
showPage.value = true;
|
||||
} catch {}
|
||||
};
|
||||
|
||||
const changeStatus = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
await operateHttps({ operate: enable.value ? 'enable' : 'disable' });
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
} catch (error) {
|
||||
enable.value = !enable.value;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getStatus();
|
||||
});
|
||||
</script>
|
Loading…
Add table
Reference in a new issue