diff --git a/internal/biz/setting.go b/internal/biz/setting.go
index bb2cf2c1..7dd8d0c5 100644
--- a/internal/biz/setting.go
+++ b/internal/biz/setting.go
@@ -9,20 +9,22 @@ import (
type SettingKey string
const (
- SettingKeyName SettingKey = "name"
- SettingKeyVersion SettingKey = "version"
- SettingKeyChannel SettingKey = "channel"
- SettingKeyMonitor SettingKey = "monitor"
- SettingKeyMonitorDays SettingKey = "monitor_days"
- SettingKeyBackupPath SettingKey = "backup_path"
- SettingKeyWebsitePath SettingKey = "website_path"
- SettingKeyMySQLRootPassword SettingKey = "mysql_root_password"
- SettingKeyOfflineMode SettingKey = "offline_mode"
- SettingKeyAutoUpdate SettingKey = "auto_update"
- SettingKeyWebserver SettingKey = "webserver"
- SettingKeyPublicIPs SettingKey = "public_ips"
- SettingHiddenMenu SettingKey = "hidden_menu"
- SettingKeyCustomLogo SettingKey = "custom_logo"
+ SettingKeyName SettingKey = "name"
+ SettingKeyVersion SettingKey = "version"
+ SettingKeyChannel SettingKey = "channel"
+ SettingKeyMonitor SettingKey = "monitor"
+ SettingKeyMonitorDays SettingKey = "monitor_days"
+ SettingKeyBackupPath SettingKey = "backup_path"
+ SettingKeyWebsitePath SettingKey = "website_path"
+ SettingKeyWebsiteTLSVersions SettingKey = "website_tls_versions"
+ SettingKeyWebsiteCipherSuites SettingKey = "website_tls_cipher_suites"
+ SettingKeyMySQLRootPassword SettingKey = "mysql_root_password"
+ SettingKeyOfflineMode SettingKey = "offline_mode"
+ SettingKeyAutoUpdate SettingKey = "auto_update"
+ SettingKeyWebserver SettingKey = "webserver"
+ SettingKeyPublicIPs SettingKey = "public_ips"
+ SettingHiddenMenu SettingKey = "hidden_menu"
+ SettingKeyCustomLogo SettingKey = "custom_logo"
)
type Setting struct {
diff --git a/internal/data/website.go b/internal/data/website.go
index 2d597f4c..5785b47a 100644
--- a/internal/data/website.go
+++ b/internal/data/website.go
@@ -84,6 +84,17 @@ func (r *websiteRepo) UpdateDefaultConfig(req *request.WebsiteDefaultConfig) err
if err := io.Write(filepath.Join(app.Root, "server/nginx/html/stop.html"), req.Stop, 0644); err != nil {
return err
}
+ if req.NotFound != "" {
+ if err := io.Write(filepath.Join(app.Root, "server/nginx/html/404.html"), req.NotFound, 0644); err != nil {
+ return err
+ }
+ }
+ if err := r.setting.SetSlice(biz.SettingKeyWebsiteTLSVersions, req.TLSVersions); err != nil {
+ return err
+ }
+ if err := r.setting.Set(biz.SettingKeyWebsiteCipherSuites, req.CipherSuites); err != nil {
+ return err
+ }
return r.reloadWebServer()
}
@@ -342,17 +353,22 @@ location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.env) {
return nil, err
}
var notFound []byte
- switch app.Locale {
- case "zh_CN":
- notFound, err = embed.WebsiteFS.ReadFile(filepath.Join("website", "404_zh_CN.html"))
- case "zh_TW":
- notFound, err = embed.WebsiteFS.ReadFile(filepath.Join("website", "404_zh_TW.html"))
- default:
- notFound, err = embed.WebsiteFS.ReadFile(filepath.Join("website", "404.html"))
- }
- if err != nil {
- return nil, errors.New(r.t.Get("failed to get 404 template file: %v", err))
+
+ // 如果存在自定义 404 页面,则使用自定义的
+ // TODO 需要兼容 Apache
+ if io.Exists(filepath.Join(app.Root, "server/nginx/html/404.html")) {
+ notFound, _ = os.ReadFile(filepath.Join(app.Root, "server/nginx/html/404.html"))
+ } else {
+ switch app.Locale {
+ case "zh_CN":
+ notFound, _ = embed.WebsiteFS.ReadFile(filepath.Join("website", "404_zh_CN.html"))
+ case "zh_TW":
+ notFound, _ = embed.WebsiteFS.ReadFile(filepath.Join("website", "404_zh_TW.html"))
+ default:
+ notFound, _ = embed.WebsiteFS.ReadFile(filepath.Join("website", "404.html"))
+ }
}
+
if err = io.Write(filepath.Join(req.Path, "404.html"), string(notFound), 0644); err != nil {
return nil, err
}
@@ -487,11 +503,13 @@ func (r *websiteRepo) Update(req *request.WebsiteUpdate) error {
break
}
}
+ defaultTLSVersions, _ := r.setting.GetSlice(biz.SettingKeyWebsiteTLSVersions)
+ defaultCipherSuites, _ := r.setting.Get(biz.SettingKeyWebsiteCipherSuites)
if err = vhost.SetSSLConfig(&webservertypes.SSLConfig{
Cert: certPath,
Key: keyPath,
- Protocols: lo.If(len(req.SSLProtocols) > 0, req.SSLProtocols).Else([]string{"TLSv1.2", "TLSv1.3"}),
- Ciphers: lo.If(req.SSLCiphers != "", req.SSLCiphers).Else("ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305"),
+ Protocols: lo.If(len(req.SSLProtocols) > 0, req.SSLProtocols).Else(defaultTLSVersions),
+ Ciphers: lo.If(req.SSLCiphers != "", req.SSLCiphers).Else(defaultCipherSuites),
HSTS: req.HSTS,
OCSP: req.OCSP,
HTTPRedirect: req.HTTPRedirect,
diff --git a/internal/http/request/website.go b/internal/http/request/website.go
index 8ca20595..c8a212ff 100644
--- a/internal/http/request/website.go
+++ b/internal/http/request/website.go
@@ -5,8 +5,11 @@ import (
)
type WebsiteDefaultConfig struct {
- Index string `json:"index" form:"index" validate:"required"`
- Stop string `json:"stop" form:"stop" validate:"required"`
+ Index string `json:"index" form:"index" validate:"required"`
+ Stop string `json:"stop" form:"stop" validate:"required"`
+ NotFound string `json:"not_found" form:"not_found"`
+ TLSVersions []string `json:"tls_versions" form:"tls_versions" validate:"required|isSlice"`
+ CipherSuites string `json:"cipher_suites" form:"cipher_suites" validate:"required"`
}
type WebsiteList struct {
diff --git a/internal/service/cli.go b/internal/service/cli.go
index 612e9fa5..07bd71d8 100644
--- a/internal/service/cli.go
+++ b/internal/service/cli.go
@@ -921,6 +921,8 @@ func (s *CliService) Init(ctx context.Context, cmd *cli.Command) error {
{Key: biz.SettingKeyMonitorDays, Value: "30"},
{Key: biz.SettingKeyBackupPath, Value: filepath.Join(app.Root, "backup")},
{Key: biz.SettingKeyWebsitePath, Value: filepath.Join(app.Root, "sites")},
+ {Key: biz.SettingKeyWebsiteTLSVersions, Value: `["TLSv1.2","TLSv1.3"]`},
+ {Key: biz.SettingKeyWebsiteCipherSuites, Value: `ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305`},
{Key: biz.SettingKeyOfflineMode, Value: "false"},
{Key: biz.SettingKeyAutoUpdate, Value: "true"},
{Key: biz.SettingHiddenMenu, Value: "[]"},
diff --git a/internal/service/website.go b/internal/service/website.go
index a1a2c506..8c9cc4bc 100644
--- a/internal/service/website.go
+++ b/internal/service/website.go
@@ -35,20 +35,18 @@ func (s *WebsiteService) GetRewrites(w http.ResponseWriter, r *http.Request) {
}
func (s *WebsiteService) GetDefaultConfig(w http.ResponseWriter, r *http.Request) {
- index, err := io.Read(filepath.Join(app.Root, "server/nginx/html/index.html"))
- if err != nil {
- Error(w, http.StatusInternalServerError, "%v", err)
- return
- }
- stop, err := io.Read(filepath.Join(app.Root, "server/nginx/html/stop.html"))
- if err != nil {
- Error(w, http.StatusInternalServerError, "%v", err)
- return
- }
+ index, _ := io.Read(filepath.Join(app.Root, "server/nginx/html/index.html"))
+ stop, _ := io.Read(filepath.Join(app.Root, "server/nginx/html/stop.html"))
+ notFound, _ := io.Read(filepath.Join(app.Root, "server/nginx/html/404.html"))
+ tlsVersions, _ := s.settingRepo.GetSlice(biz.SettingKeyWebsiteTLSVersions)
+ cipherSuites, _ := s.settingRepo.Get(biz.SettingKeyWebsiteCipherSuites)
Success(w, chix.M{
- "index": index,
- "stop": stop,
+ "index": index,
+ "stop": stop,
+ "not_found": notFound,
+ "tls_versions": tlsVersions,
+ "cipher_suites": cipherSuites,
})
}
diff --git a/web/src/api/panel/website/index.ts b/web/src/api/panel/website/index.ts
index f3113ed7..abc7985d 100644
--- a/web/src/api/panel/website/index.ts
+++ b/web/src/api/panel/website/index.ts
@@ -14,8 +14,7 @@ export default {
// 获取默认配置
defaultConfig: (): any => http.Get('/website/default_config'),
// 保存默认配置
- saveDefaultConfig: (index: string, stop: string): any =>
- http.Post('/website/default_config', { index, stop }),
+ saveDefaultConfig: (data: any): any => http.Post('/website/default_config', data),
// 网站配置
config: (id: number): any => http.Get('/website/' + id),
// 保存网站配置
diff --git a/web/src/views/website/EditView.vue b/web/src/views/website/EditView.vue
index dd95fda0..e6cbd0ef 100644
--- a/web/src/views/website/EditView.vue
+++ b/web/src/views/website/EditView.vue
@@ -323,6 +323,26 @@ const hasArg = (args: string[], arg: string) => {
+
+
+
+
+
+
{
/>
-
-
-
-
-
-
- {{
- $gettext(
- 'If you modify the original text, other modifications will not take effect after clicking save!'
- )
- }}
-
-
- {{
- $gettext(
- 'If you do not understand the configuration rules, please do not modify them arbitrarily, otherwise it may cause the website to be inaccessible or panel function abnormalities! If you have already encountered a problem, try resetting the configuration!'
- )
- }}
-
+
diff --git a/web/src/views/website/SettingView.vue b/web/src/views/website/SettingView.vue
index 3c5fe6b4..c69897bc 100644
--- a/web/src/views/website/SettingView.vue
+++ b/web/src/views/website/SettingView.vue
@@ -6,51 +6,45 @@ const { $gettext } = useGettext()
const currentTab = ref('default-page')
-const defaultPageModel = ref({
- index: '',
- not_found: '',
- stop: ''
+const { data: model } = useRequest(website.defaultConfig, {
+ initialData: {
+ index: '',
+ stop: '',
+ not_found: '',
+ tls_versions: ['TLSv1.2', 'TLSv1.3'],
+ cipher_suites: ''
+ }
})
-const defaultSettingModel = ref({
- tls_version: ['TLSv1.2', 'TLSv1.3'],
- cipher_suites: ''
-})
+watch(
+ () => model.value.tls_versions,
+ (newVal) => {
+ if (!newVal.includes('TLSv1.1') && !newVal.includes('TLSv1.0')) {
+ // 不包含 TLSv1.0 和 TLSv1.1
+ model.value.cipher_suites =
+ 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305'
+ } else {
+ // 包含 TLSv1.0 或 TLSv1.1
+ model.value.cipher_suites =
+ '@SECLEVEL=0:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA'
+ }
+ }
+)
-const getDefaultPage = async () => {
- defaultPageModel.value = await website.defaultConfig()
-}
-
-const handleSaveDefaultPage = () => {
- useRequest(
- website.saveDefaultConfig(defaultPageModel.value.index, defaultPageModel.value.stop)
- ).onSuccess(() => {
+const handleSave = () => {
+ useRequest(website.saveDefaultConfig(model.value)).onSuccess(() => {
window.$message.success($gettext('Modified successfully'))
})
}
-
-onMounted(() => {
- getDefaultPage()
-})
-
+
-
- {{ $gettext('Save Changes') }}
-
-
-
-
-
-
-
-
-
+
{{ $gettext('Save Changes') }}
@@ -58,9 +52,19 @@ onMounted(() => {
-
+
-
+
+ {{ $gettext('Save Changes') }}
+
+
+
+
+
+
+
+
+
{{ $gettext('Save Changes') }}
@@ -70,33 +74,49 @@ onMounted(() => {
待开发
-
-
-
-
-
-
-
-
- {{ $gettext('Save Changes') }}
-
-
+
+
+ {{
+ $gettext(
+ 'Modifying the default TLS version and cipher suites will affect all newly created websites. Existing websites will not be affected.'
+ )
+ }}
+
+
+ {{
+ $gettext(
+ 'Please adjust the settings carefully, improper configuration may lead to website inaccessible.'
+ )
+ }}
+
+
+
+
+
+
+
+
+
+ {{ $gettext('Save Changes') }}
+
+
+