mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-16 13:40:24 +08:00
安全设置中增加禁止搜索引擎、禁止爬虫、允许访问的域名等选项
This commit is contained in:
@@ -29,14 +29,14 @@ func (this *IndexAction) RunGet(params struct{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 国家和地区
|
// 国家和地区
|
||||||
countryMaps := []maps.Map{}
|
var countryMaps = []maps.Map{}
|
||||||
for _, countryId := range config.AllowCountryIds {
|
for _, countryId := range config.AllowCountryIds {
|
||||||
countryResp, err := this.RPC().RegionCountryRPC().FindEnabledRegionCountry(this.AdminContext(), &pb.FindEnabledRegionCountryRequest{RegionCountryId: countryId})
|
countryResp, err := this.RPC().RegionCountryRPC().FindEnabledRegionCountry(this.AdminContext(), &pb.FindEnabledRegionCountryRequest{RegionCountryId: countryId})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
country := countryResp.RegionCountry
|
var country = countryResp.RegionCountry
|
||||||
if country != nil {
|
if country != nil {
|
||||||
countryMaps = append(countryMaps, maps.Map{
|
countryMaps = append(countryMaps, maps.Map{
|
||||||
"id": country.Id,
|
"id": country.Id,
|
||||||
@@ -47,14 +47,14 @@ func (this *IndexAction) RunGet(params struct{}) {
|
|||||||
this.Data["countries"] = countryMaps
|
this.Data["countries"] = countryMaps
|
||||||
|
|
||||||
// 省份
|
// 省份
|
||||||
provinceMaps := []maps.Map{}
|
var provinceMaps = []maps.Map{}
|
||||||
for _, provinceId := range config.AllowProvinceIds {
|
for _, provinceId := range config.AllowProvinceIds {
|
||||||
provinceResp, err := this.RPC().RegionProvinceRPC().FindEnabledRegionProvince(this.AdminContext(), &pb.FindEnabledRegionProvinceRequest{RegionProvinceId: provinceId})
|
provinceResp, err := this.RPC().RegionProvinceRPC().FindEnabledRegionProvince(this.AdminContext(), &pb.FindEnabledRegionProvinceRequest{RegionProvinceId: provinceId})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
this.ErrorPage(err)
|
this.ErrorPage(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
province := provinceResp.RegionProvince
|
var province = provinceResp.RegionProvince
|
||||||
if province != nil {
|
if province != nil {
|
||||||
provinceMaps = append(provinceMaps, maps.Map{
|
provinceMaps = append(provinceMaps, maps.Map{
|
||||||
"id": province.Id,
|
"id": province.Id,
|
||||||
@@ -76,6 +76,11 @@ func (this *IndexAction) RunPost(params struct {
|
|||||||
AllowIPs []string
|
AllowIPs []string
|
||||||
AllowRememberLogin bool
|
AllowRememberLogin bool
|
||||||
|
|
||||||
|
DenySearchEngines bool
|
||||||
|
DenySpiders bool
|
||||||
|
|
||||||
|
DomainsJSON []byte
|
||||||
|
|
||||||
Must *actions.Must
|
Must *actions.Must
|
||||||
CSRF *actionutils.CSRF
|
CSRF *actionutils.CSRF
|
||||||
}) {
|
}) {
|
||||||
@@ -91,7 +96,7 @@ func (this *IndexAction) RunPost(params struct {
|
|||||||
config.Frame = params.Frame
|
config.Frame = params.Frame
|
||||||
|
|
||||||
// 国家和地区
|
// 国家和地区
|
||||||
countryIds := []int64{}
|
var countryIds = []int64{}
|
||||||
if len(params.CountryIdsJSON) > 0 {
|
if len(params.CountryIdsJSON) > 0 {
|
||||||
err = json.Unmarshal(params.CountryIdsJSON, &countryIds)
|
err = json.Unmarshal(params.CountryIdsJSON, &countryIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -102,7 +107,7 @@ func (this *IndexAction) RunPost(params struct {
|
|||||||
config.AllowCountryIds = countryIds
|
config.AllowCountryIds = countryIds
|
||||||
|
|
||||||
// 省份
|
// 省份
|
||||||
provinceIds := []int64{}
|
var provinceIds = []int64{}
|
||||||
if len(params.ProvinceIdsJSON) > 0 {
|
if len(params.ProvinceIdsJSON) > 0 {
|
||||||
err = json.Unmarshal(params.ProvinceIdsJSON, &provinceIds)
|
err = json.Unmarshal(params.ProvinceIdsJSON, &provinceIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -128,6 +133,20 @@ func (this *IndexAction) RunPost(params struct {
|
|||||||
// 允许本地
|
// 允许本地
|
||||||
config.AllowLocal = params.AllowLocal
|
config.AllowLocal = params.AllowLocal
|
||||||
|
|
||||||
|
// 禁止搜索引擎和爬虫
|
||||||
|
config.DenySearchEngines = params.DenySearchEngines
|
||||||
|
config.DenySpiders = params.DenySpiders
|
||||||
|
|
||||||
|
// 允许的域名
|
||||||
|
var domains = []string{}
|
||||||
|
if len(params.DomainsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(params.DomainsJSON, &domains)
|
||||||
|
if err != nil {
|
||||||
|
this.Fail("解析允许访问的域名失败:" + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config.AllowDomains = domains
|
||||||
|
|
||||||
// 允许记住登录
|
// 允许记住登录
|
||||||
config.AllowRememberLogin = params.AllowRememberLogin
|
config.AllowRememberLogin = params.AllowRememberLogin
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,13 @@ func (this *userMustAuth) BeforeAction(actionPtr actions.ActionWrapper, paramNam
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查请求
|
||||||
|
if !checkRequestSecurity(securityConfig, action.Request) {
|
||||||
|
action.ResponseWriter.WriteHeader(http.StatusForbidden)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 检查系统是否已经配置过
|
// 检查系统是否已经配置过
|
||||||
if !setup.IsConfigured() {
|
if !setup.IsConfigured() {
|
||||||
action.RedirectURL("/setup")
|
action.RedirectURL("/setup")
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func (this *UserShouldAuth) BeforeAction(actionPtr actions.ActionWrapper, paramN
|
|||||||
this.action = actionPtr.Object()
|
this.action = actionPtr.Object()
|
||||||
|
|
||||||
// 安全相关
|
// 安全相关
|
||||||
action := this.action
|
var action = this.action
|
||||||
securityConfig, _ := configloaders.LoadSecurityConfig()
|
securityConfig, _ := configloaders.LoadSecurityConfig()
|
||||||
if securityConfig == nil {
|
if securityConfig == nil {
|
||||||
action.AddHeader("X-Frame-Options", "SAMEORIGIN")
|
action.AddHeader("X-Frame-Options", "SAMEORIGIN")
|
||||||
@@ -42,6 +42,12 @@ func (this *UserShouldAuth) BeforeAction(actionPtr actions.ActionWrapper, paramN
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查请求
|
||||||
|
if !checkRequestSecurity(securityConfig, action.Request) {
|
||||||
|
action.ResponseWriter.WriteHeader(http.StatusForbidden)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import (
|
|||||||
"github.com/iwind/TeaGo/lists"
|
"github.com/iwind/TeaGo/lists"
|
||||||
"github.com/iwind/TeaGo/logs"
|
"github.com/iwind/TeaGo/logs"
|
||||||
"net"
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"regexp"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -106,3 +108,41 @@ func checkIPWithoutCache(config *systemconfigs.SecurityConfig, ipAddr string) bo
|
|||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 请求检查相关正则
|
||||||
|
var searchEngineRegex = regexp.MustCompile(`60spider|adldxbot|adsbot-google|applebot|admantx|alexa|baidu|bingbot|bingpreview|facebookexternalhit|googlebot|proximic|slurp|sogou|twitterbot|yandex`)
|
||||||
|
var spiderRegexp = regexp.MustCompile(`python|pycurl|http-client|httpclient|apachebench|nethttp|http_request|java|perl|ruby|scrapy|php|rust|curl|wget`) // 其中增加了curl和wget
|
||||||
|
|
||||||
|
// 检查请求
|
||||||
|
func checkRequestSecurity(securityConfig *systemconfigs.SecurityConfig, req *http.Request) bool {
|
||||||
|
if securityConfig == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
var userAgent = req.UserAgent()
|
||||||
|
var referer = req.Referer()
|
||||||
|
|
||||||
|
// 检查搜索引擎
|
||||||
|
if securityConfig.DenySearchEngines && (len(userAgent) == 0 || searchEngineRegex.MatchString(userAgent) || (len(referer) > 0 && searchEngineRegex.MatchString(referer))) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查爬虫
|
||||||
|
if securityConfig.DenySpiders && (len(userAgent) == 0 || spiderRegexp.MatchString(userAgent) || (len(referer) > 0 && spiderRegexp.MatchString(referer))) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查允许访问的域名
|
||||||
|
if len(securityConfig.AllowDomains) > 0 {
|
||||||
|
var domain = req.Host
|
||||||
|
realDomain, _, err := net.SplitHostPort(domain)
|
||||||
|
if err == nil && len(realDomain) > 0 {
|
||||||
|
domain = realDomain
|
||||||
|
}
|
||||||
|
if !lists.ContainsString(securityConfig.AllowDomains, domain) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
<td>允许局域网访问</td>
|
<td>允许局域网访问</td>
|
||||||
<td>
|
<td>
|
||||||
<checkbox name="allowLocal" v-model="config.allowLocal"></checkbox>
|
<checkbox name="allowLocal" v-model="config.allowLocal"></checkbox>
|
||||||
<p class="comment">选中表示允许在本机和局域网访问。</p>
|
<p class="comment">选中表示总是允许在本机和局域网访问,不需要其他限制条件。</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -50,6 +50,34 @@
|
|||||||
<p class="comment">选中表示允许在登录界面可以选择记住登录。</p>
|
<p class="comment">选中表示允许在登录界面可以选择记住登录。</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<more-options-indicator></more-options-indicator>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tbody v-show="moreOptionsVisible">
|
||||||
|
<tr>
|
||||||
|
<td>禁止搜索引擎</td>
|
||||||
|
<td>
|
||||||
|
<checkbox name="denySearchEngines" v-model="config.denySearchEngines"></checkbox>
|
||||||
|
<p class="comment">禁止常见的搜索引擎访问。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>禁止爬虫</td>
|
||||||
|
<td>
|
||||||
|
<checkbox name="denySpiders" v-model="config.denySpiders"></checkbox>
|
||||||
|
<p class="comment">禁止常见的爬虫访问。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>允许访问的域名</td>
|
||||||
|
<td>
|
||||||
|
<domains-box :v-domains="config.allowDomains"></domains-box>
|
||||||
|
<p class="comment">只允许通过这些域名(或者IP作为主机地址)访问当前管理系统,不填表示没有限制。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<submit-btn></submit-btn>
|
<submit-btn></submit-btn>
|
||||||
</form>
|
</form>
|
||||||
Reference in New Issue
Block a user