From b903ed5449eaaca797380035eab583b11b6f70f4 Mon Sep 17 00:00:00 2001 From: Snrat Date: Tue, 12 Aug 2025 21:18:58 +0800 Subject: [PATCH 1/2] Add HSTS Subdomains --- agent/app/dto/request/website.go | 1 + agent/app/dto/response/website.go | 1 + agent/app/service/website.go | 11 +++++++- agent/app/service/website_utils.go | 25 +++++++++++++++---- core/cmd/server/docs/docs.go | 6 +++++ core/cmd/server/docs/swagger.json | 6 +++++ frontend/src/api/interface/website.ts | 1 + frontend/src/lang/modules/en.ts | 2 ++ frontend/src/lang/modules/ja.ts | 2 ++ frontend/src/lang/modules/ko.ts | 2 ++ frontend/src/lang/modules/ms.ts | 2 ++ frontend/src/lang/modules/pt-br.ts | 2 ++ frontend/src/lang/modules/ru.ts | 2 ++ frontend/src/lang/modules/tr.ts | 2 ++ frontend/src/lang/modules/zh-Hant.ts | 2 ++ frontend/src/lang/modules/zh.ts | 2 ++ .../website/config/basic/https/index.vue | 16 ++++++++++++ 17 files changed, 79 insertions(+), 6 deletions(-) diff --git a/agent/app/dto/request/website.go b/agent/app/dto/request/website.go index 3a623ff85e0e..15c86276f955 100644 --- a/agent/app/dto/request/website.go +++ b/agent/app/dto/request/website.go @@ -165,6 +165,7 @@ type WebsiteHTTPSOp struct { SSLProtocol []string `json:"SSLProtocol"` Algorithm string `json:"algorithm"` Hsts bool `json:"hsts"` + HstsIncludeSubDomains bool `json:"hstsIncludeSubDomains"` HttpsPorts []int `json:"httpsPorts"` Http3 bool `json:"http3"` } diff --git a/agent/app/dto/response/website.go b/agent/app/dto/response/website.go index ed0ad4cdb0b3..3f4570e1a82d 100644 --- a/agent/app/dto/response/website.go +++ b/agent/app/dto/response/website.go @@ -65,6 +65,7 @@ type WebsiteHTTPS struct { SSLProtocol []string `json:"SSLProtocol"` Algorithm string `json:"algorithm"` Hsts bool `json:"hsts"` + HstsIncludeSubDomains bool `json:"hstsIncludeSubDomains"` HttpsPorts []int `json:"httpsPorts"` HttpsPort string `json:"httpsPort"` Http3 bool `json:"http3"` diff --git a/agent/app/service/website.go b/agent/app/service/website.go index 24b9ec5439d9..4b4841ebf81c 100644 --- a/agent/app/service/website.go +++ b/agent/app/service/website.go @@ -474,6 +474,7 @@ func (w WebsiteService) CreateWebsite(create request.WebsiteCreate) (err error) SSLProtocol: []string{"TLSv1.3", "TLSv1.2"}, Algorithm: "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK:!KRB5:!SRP:!CAMELLIA:!SEED", Hsts: true, + HstsIncludeSubDomains: true, } if err = applySSL(website, *websiteModel, appSSLReq); err != nil { return err @@ -959,6 +960,13 @@ func (w WebsiteService) GetWebsiteHTTPS(websiteId uint) (response.WebsiteHTTPS, if p.Name == "add_header" && len(p.Params) > 0 { if p.Params[0] == "Strict-Transport-Security" { res.Hsts = true + //增加HSTS下子域名检查逻辑 + if len(p.Params) > 1 { + hstsValue := p.Params[1] + if strings.Contains(hstsValue, "includeSubDomains") { + res.HstsIncludeSubDomains = true + } + } } if p.Params[0] == "Alt-Svc" { res.Http3 = true @@ -977,12 +985,13 @@ func (w WebsiteService) OpWebsiteHTTPS(ctx context.Context, req request.WebsiteH res response.WebsiteHTTPS websiteSSL model.WebsiteSSL ) - if err = ChangeHSTSConfig(req.Hsts, req.Http3, website); err != nil { + if err = ChangeHSTSConfig(req.Hsts, req.HstsIncludeSubDomains, req.Http3, website); err != nil { return nil, err } res.Enable = req.Enable res.SSLProtocol = req.SSLProtocol res.Algorithm = req.Algorithm + res.HstsIncludeSubDomains = req.HstsIncludeSubDomains if !req.Enable { website.Protocol = constant.ProtocolHTTP website.WebsiteSSLID = 0 diff --git a/agent/app/service/website_utils.go b/agent/app/service/website_utils.go index 5298cce9ae3e..1fa887b8f898 100644 --- a/agent/app/service/website_utils.go +++ b/agent/app/service/website_utils.go @@ -753,6 +753,7 @@ func applySSL(website *model.Website, websiteSSL model.WebsiteSSL, req request.W if !req.Hsts { server.RemoveDirective("add_header", []string{"Strict-Transport-Security", "\"max-age=31536000\""}) + server.RemoveDirective("add_header", []string{"Strict-Transport-Security", "\"max-age=31536000; includeSubDomains\""}) } if !req.Http3 { for port := range httpsPorts { @@ -793,9 +794,15 @@ func applySSL(website *model.Website, websiteSSL model.WebsiteSSL, req request.W } } if req.Hsts { + var hstsValue string + if req.HstsIncludeSubDomains { + hstsValue = "\"max-age=31536000; includeSubDomains\"" + } else { + hstsValue = "\"max-age=31536000\"" + } nginxParams = append(nginxParams, dto.NginxParam{ Name: "add_header", - Params: []string{"Strict-Transport-Security", "\"max-age=31536000\""}, + Params: []string{"Strict-Transport-Security", hstsValue}, }) } if req.Http3 { @@ -1182,7 +1189,7 @@ func UpdateSSLConfig(websiteSSL model.WebsiteSSL) error { return nil } -func ChangeHSTSConfig(enable bool, http3Enable bool, website model.Website) error { +func ChangeHSTSConfig(enable bool, includeSubDomains bool, http3Enable bool, website model.Website) error { includeDir := GetSitePath(website, SiteProxyDir) fileOp := files.NewFileOp() if !fileOp.Stat(includeDir) { @@ -1208,11 +1215,19 @@ func ChangeHSTSConfig(enable bool, http3Enable bool, website model.Website) erro if !ok { return nil } + //前置移除HSTS配置 + location.RemoveDirective("add_header", []string{"Strict-Transport-Security", "\"max-age=31536000\""}) + location.RemoveDirective("add_header", []string{"Strict-Transport-Security", "\"max-age=31536000; includeSubDomains\""}) if enable { - location.UpdateDirective("add_header", []string{"Strict-Transport-Security", "\"max-age=31536000\""}) - } else { - location.RemoveDirective("add_header", []string{"Strict-Transport-Security", "\"max-age=31536000\""}) + var hstsValue string + if includeSubDomains { + hstsValue = "\"max-age=31536000; includeSubDomains\"" + } else { + hstsValue = "\"max-age=31536000\"" + } + location.UpdateDirective("add_header", []string{"Strict-Transport-Security", hstsValue}) } + if http3Enable { location.UpdateDirective("add_header", []string{"Alt-Svc", "'h3=\":443\"; ma=2592000'"}) } else { diff --git a/core/cmd/server/docs/docs.go b/core/cmd/server/docs/docs.go index a345f8c1bb22..e8abcfd5ab47 100644 --- a/core/cmd/server/docs/docs.go +++ b/core/cmd/server/docs/docs.go @@ -26932,6 +26932,9 @@ const docTemplate = `{ "hsts": { "type": "boolean" }, + "hstsIncludeSubDomains": { + "type": "boolean" + }, "http3": { "type": "boolean" }, @@ -28911,6 +28914,9 @@ const docTemplate = `{ "hsts": { "type": "boolean" }, + "hstsIncludeSubDomains": { + "type": "boolean" + }, "http3": { "type": "boolean" }, diff --git a/core/cmd/server/docs/swagger.json b/core/cmd/server/docs/swagger.json index 8590c011e14c..ed649e530e55 100644 --- a/core/cmd/server/docs/swagger.json +++ b/core/cmd/server/docs/swagger.json @@ -26928,6 +26928,9 @@ "hsts": { "type": "boolean" }, + "hstsIncludeSubDomains": { + "type": "boolean" + }, "http3": { "type": "boolean" }, @@ -28907,6 +28910,9 @@ "hsts": { "type": "boolean" }, + "hstsIncludeSubDomains": { + "type": "boolean" + }, "http3": { "type": "boolean" }, diff --git a/frontend/src/api/interface/website.ts b/frontend/src/api/interface/website.ts index bef6ff6aa872..4e79f75acb62 100644 --- a/frontend/src/api/interface/website.ts +++ b/frontend/src/api/interface/website.ts @@ -318,6 +318,7 @@ export namespace Website { SSLProtocol: string[]; algorithm: string; hsts: boolean; + hstsIncludeSubDomains: boolean; httpsPort?: string; http3: boolean; } diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index b649b9922e16..1083d37326b1 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -2434,6 +2434,8 @@ const message = { 'Only supports importing local backups, importing backups from other machines may cause recovery failure', ipWebsiteWarn: 'Websites with IP as domain names need to be set as default site to be accessed normally.', hstsHelper: 'Enabling HSTS can increase website security', + includeSubDomains: 'SubDomains', + hstsIncludeSubDomainsHelper: 'Once enabled, the HSTS policy will apply to all subdomains of the current domain.', defaultHtml: 'Set default page', website404: 'Website 404 error page', domain404: 'Website page does not exist', diff --git a/frontend/src/lang/modules/ja.ts b/frontend/src/lang/modules/ja.ts index b65ffc0bc312..b167f47d9bc6 100644 --- a/frontend/src/lang/modules/ja.ts +++ b/frontend/src/lang/modules/ja.ts @@ -2349,6 +2349,8 @@ const message = { ipWebsiteWarn: 'ドメイン名としてIPを持つWebサイトは、正常にアクセスするデフォルトサイトとして設定する必要があります。', hstsHelper: 'HSTを有効にすると、Webサイトのセキュリティが向上する可能性があります', + includeSubDomains: 'サブドメイン', + hstsIncludeSubDomainsHelper: '有効化すると、HSTSポリシーが現在のドメインのすべてのサブドメインに適用されます。', defaultHtml: 'デフォルトページ', website404: 'ウェブサイト404エラーページ', domain404: 'ウェブサイトドメインは存在しません', diff --git a/frontend/src/lang/modules/ko.ts b/frontend/src/lang/modules/ko.ts index 35ed3bc44362..894f2744255a 100644 --- a/frontend/src/lang/modules/ko.ts +++ b/frontend/src/lang/modules/ko.ts @@ -2309,6 +2309,8 @@ const message = { ipWebsiteWarn: 'IP를 도메인 이름으로 사용하는 웹사이트는 정상적으로 접속되기 위해 기본 사이트로 설정해야 합니다.', hstsHelper: 'HSTS 를 활성화하면 웹사이트 보안을 강화할 수 있습니다.', + includeSubDomains: '서브도메인', + hstsIncludeSubDomainsHelper: '활성화하면 HSTS 정책이 현재 도메인의 모든 서브도메인에 적용됩니다.', defaultHtml: '기본 페이지', website404: '웹사이트 404 오류 페이지', domain404: '웹사이트 도메인이 존재하지 않습니다.', diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts index d5100d6ed8c1..491e2b6b1e1b 100644 --- a/frontend/src/lang/modules/ms.ts +++ b/frontend/src/lang/modules/ms.ts @@ -2404,6 +2404,8 @@ const message = { ipWebsiteWarn: 'Laman web dengan IP sebagai nama domain perlu disetkan sebagai laman web lalai untuk diakses secara normal.', hstsHelper: 'Mengaktifkan HSTS boleh meningkatkan keselamatan laman web', + includeSubDomains: 'SubDomains', + hstsIncludeSubDomainsHelper: 'Apabila diaktifkan, dasar HSTS akan digunakan pada semua subdomain bagi domain semasa.', defaultHtml: 'Halaman lalai', website404: 'Halaman ralat 404 laman web', domain404: 'Domain laman web tidak wujud', diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts index cd9c7a65d12a..df4dd176b34a 100644 --- a/frontend/src/lang/modules/pt-br.ts +++ b/frontend/src/lang/modules/pt-br.ts @@ -2404,6 +2404,8 @@ const message = { ipWebsiteWarn: 'Sites com IP como nomes de domínio precisam ser configurados como site padrão para serem acessados normalmente', hstsHelper: 'Ativar HSTS pode aumentar a segurança do site', + includeSubDomains: 'SubDomains', + hstsIncludeSubDomainsHelper: 'Quando ativado, a política HSTS será aplicada a todos os subdomínios do domínio atual.', defaultHtml: 'Página padrão', website404: 'Página de erro 404 do site', domain404: 'O domínio do site não existe', diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts index d579289918a5..685e3f23083b 100644 --- a/frontend/src/lang/modules/ru.ts +++ b/frontend/src/lang/modules/ru.ts @@ -2400,6 +2400,8 @@ const message = { ipWebsiteWarn: 'Веб-сайты с IP в качестве домена должны быть установлены как сайт по умолчанию для нормального доступа.', hstsHelper: 'Включение HSTS может повысить безопасность веб-сайта', + includeSubDomains: 'Поддомены', + hstsIncludeSubDomainsHelper: 'После включения политика HSTS будет применяться ко всем поддоменам текущего домена.', defaultHtml: 'Страница по умолчанию', website404: 'Страница ошибки 404 веб-сайта', domain404: 'Домен веб-сайта не существует', diff --git a/frontend/src/lang/modules/tr.ts b/frontend/src/lang/modules/tr.ts index 92554c780ddf..3a914075f457 100644 --- a/frontend/src/lang/modules/tr.ts +++ b/frontend/src/lang/modules/tr.ts @@ -2463,6 +2463,8 @@ const message = { ipWebsiteWarn: 'IP alan adlarına sahip web sitelerinin normal şekilde erişilebilmesi için varsayılan site olarak ayarlanması gerekir.', hstsHelper: 'HSTS’nin etkinleştirilmesi web sitesi güvenliğini artırabilir', + includeSubDomains: 'Alt Alan Adları', + hstsIncludeSubDomainsHelper: 'Etkinleştirildiğinde, HSTS politikası geçerli etki alanının tüm alt alan adlarına uygulanacaktır.', defaultHtml: 'Varsayılan sayfayı ayarla', website404: 'Web sitesi 404 hata sayfası', domain404: 'Web sitesi sayfası mevcut değil', diff --git a/frontend/src/lang/modules/zh-Hant.ts b/frontend/src/lang/modules/zh-Hant.ts index 2e1f680f7994..9bda6e33457d 100644 --- a/frontend/src/lang/modules/zh-Hant.ts +++ b/frontend/src/lang/modules/zh-Hant.ts @@ -2272,6 +2272,8 @@ const message = { websiteBackupWarn: '僅支援導入本機備份,導入其他機器備份可能會恢復失敗', ipWebsiteWarn: 'IP 為網域名稱的網站,需要設定為預設網站才能正常存取', hstsHelper: '開啟 HSTS 可以增加網站安全性', + includeSubDomains: '子域', + hstsIncludeSubDomainsHelper: '啟用後,HSTS策略將應用於目前域名的所有子域名', defaultHtml: '預設頁面', website404: '網站 404 錯誤頁', domain404: '網站不存在頁面', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 1a94fd4af67f..70848819b70b 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -2261,6 +2261,8 @@ const message = { websiteBackupWarn: '仅支持导入本机备份,导入其他机器备份可能会恢复失败', ipWebsiteWarn: 'IP 为域名的网站,需要设置为默认站点才能正常访问', hstsHelper: '开启 HSTS 可以增加网站安全性', + includeSubDomains: '子域', + hstsIncludeSubDomainsHelper: '启用后,HSTS策略将应用于当前域名的所有子域名', defaultHtml: '默认页面', website404: '网站 404 错误页', domain404: '网站不存在页', diff --git a/frontend/src/views/website/website/config/basic/https/index.vue b/frontend/src/views/website/website/config/basic/https/index.vue index 446d6f197889..c8d228070636 100644 --- a/frontend/src/views/website/website/config/basic/https/index.vue +++ b/frontend/src/views/website/website/config/basic/https/index.vue @@ -29,6 +29,18 @@ {{ $t('commons.button.enable') }} {{ $t('website.hstsHelper') }} + + + {{ $t('commons.button.enable') }} + + + {{ $t('website.hstsIncludeSubDomainsHelper') }} + + {{ $t('commons.button.enable') }} {{ $t('website.http3Helper') }} @@ -205,6 +217,7 @@ const form = reactive({ certificatePath: '', httpConfig: 'HTTPToHTTPS', hsts: true, + hstsIncludeSubDomains: false, algorithm: 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK:!KRB5:!SRP:!CAMELLIA:!SEED', SSLProtocol: ['TLSv1.3', 'TLSv1.2'], @@ -314,6 +327,7 @@ const get = () => { form.acmeAccountID = data.SSL.acmeAccountId; } form.hsts = data.hsts; + form.hstsIncludeSubDomains = data.hstsIncludeSubDomains || false; form.http3 = data.http3; form.httpsPort = data.httpsPort; } @@ -344,6 +358,8 @@ const changeEnable = (enable: boolean) => { if (enable) { listSSLs(); form.hsts = true; + } else { + form.hstsIncludeSubDomains = false; } if (resData.value.enable && !enable) { ElMessageBox.confirm(i18n.global.t('website.disableHTTPSHelper'), i18n.global.t('website.disableHTTPS'), { From 901011f03434ebc1a43d037b54448d52463d847e Mon Sep 17 00:00:00 2001 From: Snrat Date: Tue, 12 Aug 2025 22:13:26 +0800 Subject: [PATCH 2/2] Fix Prettier Error --- frontend/src/lang/modules/en.ts | 3 ++- frontend/src/lang/modules/ms.ts | 3 ++- frontend/src/lang/modules/pt-br.ts | 3 ++- frontend/src/lang/modules/ru.ts | 3 ++- frontend/src/lang/modules/tr.ts | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 7655a5ed49ea..6e578a54ef3a 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -2436,7 +2436,8 @@ const message = { ipWebsiteWarn: 'Websites with IP as domain names need to be set as default site to be accessed normally.', hstsHelper: 'Enabling HSTS can increase website security', includeSubDomains: 'SubDomains', - hstsIncludeSubDomainsHelper: 'Once enabled, the HSTS policy will apply to all subdomains of the current domain.', + hstsIncludeSubDomainsHelper: + 'Once enabled, the HSTS policy will apply to all subdomains of the current domain.', defaultHtml: 'Set default page', website404: 'Website 404 error page', domain404: 'Website page does not exist', diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts index bead083688b3..d17580ffadd1 100644 --- a/frontend/src/lang/modules/ms.ts +++ b/frontend/src/lang/modules/ms.ts @@ -2406,7 +2406,8 @@ const message = { 'Laman web dengan IP sebagai nama domain perlu disetkan sebagai laman web lalai untuk diakses secara normal.', hstsHelper: 'Mengaktifkan HSTS boleh meningkatkan keselamatan laman web', includeSubDomains: 'SubDomains', - hstsIncludeSubDomainsHelper: 'Apabila diaktifkan, dasar HSTS akan digunakan pada semua subdomain bagi domain semasa.', + hstsIncludeSubDomainsHelper: + 'Apabila diaktifkan, dasar HSTS akan digunakan pada semua subdomain bagi domain semasa.', defaultHtml: 'Halaman lalai', website404: 'Halaman ralat 404 laman web', domain404: 'Domain laman web tidak wujud', diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts index a54b605aebe6..510107d04d3f 100644 --- a/frontend/src/lang/modules/pt-br.ts +++ b/frontend/src/lang/modules/pt-br.ts @@ -2406,7 +2406,8 @@ const message = { 'Sites com IP como nomes de domínio precisam ser configurados como site padrão para serem acessados normalmente', hstsHelper: 'Ativar HSTS pode aumentar a segurança do site', includeSubDomains: 'SubDomains', - hstsIncludeSubDomainsHelper: 'Quando ativado, a política HSTS será aplicada a todos os subdomínios do domínio atual.', + hstsIncludeSubDomainsHelper: + 'Quando ativado, a política HSTS será aplicada a todos os subdomínios do domínio atual.', defaultHtml: 'Página padrão', website404: 'Página de erro 404 do site', domain404: 'O domínio do site não existe', diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts index 807f9135c4f2..f618ee6ffe9a 100644 --- a/frontend/src/lang/modules/ru.ts +++ b/frontend/src/lang/modules/ru.ts @@ -2402,7 +2402,8 @@ const message = { 'Веб-сайты с IP в качестве домена должны быть установлены как сайт по умолчанию для нормального доступа.', hstsHelper: 'Включение HSTS может повысить безопасность веб-сайта', includeSubDomains: 'Поддомены', - hstsIncludeSubDomainsHelper: 'После включения политика HSTS будет применяться ко всем поддоменам текущего домена.', + hstsIncludeSubDomainsHelper: + 'После включения политика HSTS будет применяться ко всем поддоменам текущего домена.', defaultHtml: 'Страница по умолчанию', website404: 'Страница ошибки 404 веб-сайта', domain404: 'Домен веб-сайта не существует', diff --git a/frontend/src/lang/modules/tr.ts b/frontend/src/lang/modules/tr.ts index 6c302f4b6900..cab52856c09b 100644 --- a/frontend/src/lang/modules/tr.ts +++ b/frontend/src/lang/modules/tr.ts @@ -2465,7 +2465,8 @@ const message = { 'IP alan adlarına sahip web sitelerinin normal şekilde erişilebilmesi için varsayılan site olarak ayarlanması gerekir.', hstsHelper: 'HSTS’nin etkinleştirilmesi web sitesi güvenliğini artırabilir', includeSubDomains: 'Alt Alan Adları', - hstsIncludeSubDomainsHelper: 'Etkinleştirildiğinde, HSTS politikası geçerli etki alanının tüm alt alan adlarına uygulanacaktır.', + hstsIncludeSubDomainsHelper: + 'Etkinleştirildiğinde, HSTS politikası geçerli etki alanının tüm alt alan adlarına uygulanacaktır.', defaultHtml: 'Varsayılan sayfayı ayarla', website404: 'Web sitesi 404 hata sayfası', domain404: 'Web sitesi sayfası mevcut değil',