Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
cc9a559b
authored
Sep 16, 2025
by
creamlike1024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 添加域名和ip过滤模式设置
parent
c3f54785
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
98 additions
and
36 deletions
+98
-36
service/download.go
+2
-2
service/user_notify.go
+1
-1
service/webhook.go
+1
-1
setting/system_setting/fetch_setting.go
+8
-4
web/src/components/settings/SystemSetting.jsx
+86
-28
No files found.
service/download.go
View file @
cc9a559b
...
@@ -30,7 +30,7 @@ func DoWorkerRequest(req *WorkerRequest) (*http.Response, error) {
...
@@ -30,7 +30,7 @@ func DoWorkerRequest(req *WorkerRequest) (*http.Response, error) {
// SSRF防护:验证请求URL
// SSRF防护:验证请求URL
fetchSetting
:=
system_setting
.
GetFetchSetting
()
fetchSetting
:=
system_setting
.
GetFetchSetting
()
if
err
:=
common
.
ValidateURLWithFetchSetting
(
req
.
URL
,
fetchSetting
.
EnableSSRFProtection
,
fetchSetting
.
AllowPrivateIp
,
fetchSetting
.
WhitelistDomains
,
fetchSetting
.
WhitelistIps
,
fetchSetting
.
AllowedPorts
);
err
!=
nil
{
if
err
:=
common
.
ValidateURLWithFetchSetting
(
req
.
URL
,
fetchSetting
.
EnableSSRFProtection
,
fetchSetting
.
AllowPrivateIp
,
fetchSetting
.
DomainList
,
fetchSetting
.
IpList
,
fetchSetting
.
AllowedPorts
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"request reject: %v"
,
err
)
return
nil
,
fmt
.
Errorf
(
"request reject: %v"
,
err
)
}
}
...
@@ -59,7 +59,7 @@ func DoDownloadRequest(originUrl string, reason ...string) (resp *http.Response,
...
@@ -59,7 +59,7 @@ func DoDownloadRequest(originUrl string, reason ...string) (resp *http.Response,
}
else
{
}
else
{
// SSRF防护:验证请求URL(非Worker模式)
// SSRF防护:验证请求URL(非Worker模式)
fetchSetting
:=
system_setting
.
GetFetchSetting
()
fetchSetting
:=
system_setting
.
GetFetchSetting
()
if
err
:=
common
.
ValidateURLWithFetchSetting
(
originUrl
,
fetchSetting
.
EnableSSRFProtection
,
fetchSetting
.
AllowPrivateIp
,
fetchSetting
.
WhitelistDomains
,
fetchSetting
.
WhitelistIps
,
fetchSetting
.
AllowedPorts
);
err
!=
nil
{
if
err
:=
common
.
ValidateURLWithFetchSetting
(
originUrl
,
fetchSetting
.
EnableSSRFProtection
,
fetchSetting
.
AllowPrivateIp
,
fetchSetting
.
DomainList
,
fetchSetting
.
IpList
,
fetchSetting
.
AllowedPorts
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"request reject: %v"
,
err
)
return
nil
,
fmt
.
Errorf
(
"request reject: %v"
,
err
)
}
}
...
...
service/user_notify.go
View file @
cc9a559b
...
@@ -115,7 +115,7 @@ func sendBarkNotify(barkURL string, data dto.Notify) error {
...
@@ -115,7 +115,7 @@ func sendBarkNotify(barkURL string, data dto.Notify) error {
}
else
{
}
else
{
// SSRF防护:验证Bark URL(非Worker模式)
// SSRF防护:验证Bark URL(非Worker模式)
fetchSetting
:=
system_setting
.
GetFetchSetting
()
fetchSetting
:=
system_setting
.
GetFetchSetting
()
if
err
:=
common
.
ValidateURLWithFetchSetting
(
finalURL
,
fetchSetting
.
EnableSSRFProtection
,
fetchSetting
.
AllowPrivateIp
,
fetchSetting
.
WhitelistDomains
,
fetchSetting
.
WhitelistIps
,
fetchSetting
.
AllowedPorts
);
err
!=
nil
{
if
err
:=
common
.
ValidateURLWithFetchSetting
(
finalURL
,
fetchSetting
.
EnableSSRFProtection
,
fetchSetting
.
AllowPrivateIp
,
fetchSetting
.
DomainList
,
fetchSetting
.
IpList
,
fetchSetting
.
AllowedPorts
);
err
!=
nil
{
return
fmt
.
Errorf
(
"request reject: %v"
,
err
)
return
fmt
.
Errorf
(
"request reject: %v"
,
err
)
}
}
...
...
service/webhook.go
View file @
cc9a559b
...
@@ -89,7 +89,7 @@ func SendWebhookNotify(webhookURL string, secret string, data dto.Notify) error
...
@@ -89,7 +89,7 @@ func SendWebhookNotify(webhookURL string, secret string, data dto.Notify) error
}
else
{
}
else
{
// SSRF防护:验证Webhook URL(非Worker模式)
// SSRF防护:验证Webhook URL(非Worker模式)
fetchSetting
:=
system_setting
.
GetFetchSetting
()
fetchSetting
:=
system_setting
.
GetFetchSetting
()
if
err
:=
common
.
ValidateURLWithFetchSetting
(
webhookURL
,
fetchSetting
.
EnableSSRFProtection
,
fetchSetting
.
AllowPrivateIp
,
fetchSetting
.
WhitelistDomains
,
fetchSetting
.
WhitelistIps
,
fetchSetting
.
AllowedPorts
);
err
!=
nil
{
if
err
:=
common
.
ValidateURLWithFetchSetting
(
webhookURL
,
fetchSetting
.
EnableSSRFProtection
,
fetchSetting
.
AllowPrivateIp
,
fetchSetting
.
DomainList
,
fetchSetting
.
IpList
,
fetchSetting
.
AllowedPorts
);
err
!=
nil
{
return
fmt
.
Errorf
(
"request reject: %v"
,
err
)
return
fmt
.
Errorf
(
"request reject: %v"
,
err
)
}
}
...
...
setting/system_setting/fetch_setting.go
View file @
cc9a559b
...
@@ -5,16 +5,20 @@ import "one-api/setting/config"
...
@@ -5,16 +5,20 @@ import "one-api/setting/config"
type
FetchSetting
struct
{
type
FetchSetting
struct
{
EnableSSRFProtection
bool
`json:"enable_ssrf_protection"`
// 是否启用SSRF防护
EnableSSRFProtection
bool
`json:"enable_ssrf_protection"`
// 是否启用SSRF防护
AllowPrivateIp
bool
`json:"allow_private_ip"`
AllowPrivateIp
bool
`json:"allow_private_ip"`
WhitelistDomains
[]
string
`json:"whitelist_domains"`
// domain format, e.g. example.com, *.example.com
DomainFilterMode
bool
`json:"domain_filter_mode"`
// 域名过滤模式,true: 白名单模式,false: 黑名单模式
WhitelistIps
[]
string
`json:"whitelist_ips"`
// CIDR format
IpFilterMode
bool
`json:"ip_filter_mode"`
// IP过滤模式,true: 白名单模式,false: 黑名单模式
DomainList
[]
string
`json:"domain_list"`
// domain format, e.g. example.com, *.example.com
IpList
[]
string
`json:"ip_list"`
// CIDR format
AllowedPorts
[]
string
`json:"allowed_ports"`
// port range format, e.g. 80, 443, 8000-9000
AllowedPorts
[]
string
`json:"allowed_ports"`
// port range format, e.g. 80, 443, 8000-9000
}
}
var
defaultFetchSetting
=
FetchSetting
{
var
defaultFetchSetting
=
FetchSetting
{
EnableSSRFProtection
:
true
,
// 默认开启SSRF防护
EnableSSRFProtection
:
true
,
// 默认开启SSRF防护
AllowPrivateIp
:
false
,
AllowPrivateIp
:
false
,
WhitelistDomains
:
[]
string
{},
DomainFilterMode
:
true
,
WhitelistIps
:
[]
string
{},
IpFilterMode
:
true
,
DomainList
:
[]
string
{},
IpList
:
[]
string
{},
AllowedPorts
:
[]
string
{
"80"
,
"443"
,
"8080"
,
"8443"
},
AllowedPorts
:
[]
string
{
"80"
,
"443"
,
"8080"
,
"8443"
},
}
}
...
...
web/src/components/settings/SystemSetting.jsx
View file @
cc9a559b
...
@@ -29,6 +29,7 @@ import {
...
@@ -29,6 +29,7 @@ import {
TagInput
,
TagInput
,
Spin
,
Spin
,
Card
,
Card
,
Radio
,
}
from
'@douyinfe/semi-ui'
;
}
from
'@douyinfe/semi-ui'
;
const
{
Text
}
=
Typography
;
const
{
Text
}
=
Typography
;
import
{
import
{
...
@@ -91,8 +92,10 @@ const SystemSetting = () => {
...
@@ -91,8 +92,10 @@ const SystemSetting = () => {
// SSRF防护配置
// SSRF防护配置
'fetch_setting.enable_ssrf_protection'
:
true
,
'fetch_setting.enable_ssrf_protection'
:
true
,
'fetch_setting.allow_private_ip'
:
''
,
'fetch_setting.allow_private_ip'
:
''
,
'fetch_setting.whitelist_domains'
:
[],
'fetch_setting.domain_filter_mode'
:
true
,
// true 白名单,false 黑名单
'fetch_setting.whitelist_ips'
:
[],
'fetch_setting.ip_filter_mode'
:
true
,
// true 白名单,false 黑名单
'fetch_setting.domain_list'
:
[],
'fetch_setting.ip_list'
:
[],
'fetch_setting.allowed_ports'
:
[],
'fetch_setting.allowed_ports'
:
[],
});
});
...
@@ -105,8 +108,10 @@ const SystemSetting = () => {
...
@@ -105,8 +108,10 @@ const SystemSetting = () => {
useState
(
false
);
useState
(
false
);
const
[
linuxDOOAuthEnabled
,
setLinuxDOOAuthEnabled
]
=
useState
(
false
);
const
[
linuxDOOAuthEnabled
,
setLinuxDOOAuthEnabled
]
=
useState
(
false
);
const
[
emailToAdd
,
setEmailToAdd
]
=
useState
(
''
);
const
[
emailToAdd
,
setEmailToAdd
]
=
useState
(
''
);
const
[
whitelistDomains
,
setWhitelistDomains
]
=
useState
([]);
const
[
domainFilterMode
,
setDomainFilterMode
]
=
useState
(
true
);
const
[
whitelistIps
,
setWhitelistIps
]
=
useState
([]);
const
[
ipFilterMode
,
setIpFilterMode
]
=
useState
(
true
);
const
[
domainList
,
setDomainList
]
=
useState
([]);
const
[
ipList
,
setIpList
]
=
useState
([]);
const
[
allowedPorts
,
setAllowedPorts
]
=
useState
([]);
const
[
allowedPorts
,
setAllowedPorts
]
=
useState
([]);
const
getOptions
=
async
()
=>
{
const
getOptions
=
async
()
=>
{
...
@@ -125,22 +130,24 @@ const SystemSetting = () => {
...
@@ -125,22 +130,24 @@ const SystemSetting = () => {
break
;
break
;
case
'fetch_setting.allow_private_ip'
:
case
'fetch_setting.allow_private_ip'
:
case
'fetch_setting.enable_ssrf_protection'
:
case
'fetch_setting.enable_ssrf_protection'
:
case
'fetch_setting.domain_filter_mode'
:
case
'fetch_setting.ip_filter_mode'
:
item
.
value
=
toBoolean
(
item
.
value
);
item
.
value
=
toBoolean
(
item
.
value
);
break
;
break
;
case
'fetch_setting.
whitelist_domains
'
:
case
'fetch_setting.
domain_list
'
:
try
{
try
{
const
domains
=
item
.
value
?
JSON
.
parse
(
item
.
value
)
:
[];
const
domains
=
item
.
value
?
JSON
.
parse
(
item
.
value
)
:
[];
set
WhitelistDomains
(
Array
.
isArray
(
domains
)
?
domains
:
[]);
set
DomainList
(
Array
.
isArray
(
domains
)
?
domains
:
[]);
}
catch
(
e
)
{
}
catch
(
e
)
{
set
WhitelistDomains
([]);
set
DomainList
([]);
}
}
break
;
break
;
case
'fetch_setting.
whitelist_ips
'
:
case
'fetch_setting.
ip_list
'
:
try
{
try
{
const
ips
=
item
.
value
?
JSON
.
parse
(
item
.
value
)
:
[];
const
ips
=
item
.
value
?
JSON
.
parse
(
item
.
value
)
:
[];
set
WhitelistIps
(
Array
.
isArray
(
ips
)
?
ips
:
[]);
set
IpList
(
Array
.
isArray
(
ips
)
?
ips
:
[]);
}
catch
(
e
)
{
}
catch
(
e
)
{
set
WhitelistIps
([]);
set
IpList
([]);
}
}
break
;
break
;
case
'fetch_setting.allowed_ports'
:
case
'fetch_setting.allowed_ports'
:
...
@@ -178,6 +185,13 @@ const SystemSetting = () => {
...
@@ -178,6 +185,13 @@ const SystemSetting = () => {
});
});
setInputs
(
newInputs
);
setInputs
(
newInputs
);
setOriginInputs
(
newInputs
);
setOriginInputs
(
newInputs
);
// 同步模式布尔到本地状态
if
(
typeof
newInputs
[
'fetch_setting.domain_filter_mode'
]
!==
'undefined'
)
{
setDomainFilterMode
(
!!
newInputs
[
'fetch_setting.domain_filter_mode'
]);
}
if
(
typeof
newInputs
[
'fetch_setting.ip_filter_mode'
]
!==
'undefined'
)
{
setIpFilterMode
(
!!
newInputs
[
'fetch_setting.ip_filter_mode'
]);
}
if
(
formApiRef
.
current
)
{
if
(
formApiRef
.
current
)
{
formApiRef
.
current
.
setValues
(
newInputs
);
formApiRef
.
current
.
setValues
(
newInputs
);
}
}
...
@@ -317,19 +331,27 @@ const SystemSetting = () => {
...
@@ -317,19 +331,27 @@ const SystemSetting = () => {
const
submitSSRF
=
async
()
=>
{
const
submitSSRF
=
async
()
=>
{
const
options
=
[];
const
options
=
[];
// 处理域名白名单
// 处理域名过滤模式与列表
if
(
Array
.
isArray
(
whitelistDomains
))
{
options
.
push
({
options
.
push
({
key
:
'fetch_setting.whitelist_domains'
,
key
:
'fetch_setting.domain_filter_mode'
,
value
:
JSON
.
stringify
(
whitelistDomains
),
value
:
domainFilterMode
,
});
if
(
Array
.
isArray
(
domainList
))
{
options
.
push
({
key
:
'fetch_setting.domain_list'
,
value
:
JSON
.
stringify
(
domainList
),
});
});
}
}
// 处理IP白名单
// 处理IP过滤模式与列表
if
(
Array
.
isArray
(
whitelistIps
))
{
options
.
push
({
options
.
push
({
key
:
'fetch_setting.whitelist_ips'
,
key
:
'fetch_setting.ip_filter_mode'
,
value
:
JSON
.
stringify
(
whitelistIps
),
value
:
ipFilterMode
,
});
if
(
Array
.
isArray
(
ipList
))
{
options
.
push
({
key
:
'fetch_setting.ip_list'
,
value
:
JSON
.
stringify
(
ipList
),
});
});
}
}
...
@@ -702,25 +724,43 @@ const SystemSetting = () => {
...
@@ -702,25 +724,43 @@ const SystemSetting = () => {
style=
{
{
marginTop
:
16
}
}
style=
{
{
marginTop
:
16
}
}
>
>
<
Col
xs=
{
24
}
sm=
{
24
}
md=
{
24
}
lg=
{
24
}
xl=
{
24
}
>
<
Col
xs=
{
24
}
sm=
{
24
}
md=
{
24
}
lg=
{
24
}
xl=
{
24
}
>
<
Text
strong
>
{
t
(
'域名白名单'
)
}
</
Text
>
<
Text
strong
>
{
t
(
domainFilterMode
?
'域名白名单'
:
'域名黑名单'
)
}
</
Text
>
<
Text
type=
"secondary"
style=
{
{
display
:
'block'
,
marginBottom
:
8
}
}
>
<
Text
type=
"secondary"
style=
{
{
display
:
'block'
,
marginBottom
:
8
}
}
>
{
t
(
'支持通配符格式,如:example.com, *.api.example.com'
)
}
{
t
(
'支持通配符格式,如:example.com, *.api.example.com'
)
}
</
Text
>
</
Text
>
<
Radio
.
Group
type=
'button'
value=
{
domainFilterMode
?
'whitelist'
:
'blacklist'
}
onChange=
{
(
val
)
=>
{
const
isWhitelist
=
val
===
'whitelist'
;
setDomainFilterMode
(
isWhitelist
);
setInputs
(
prev
=>
({
...
prev
,
'fetch_setting.domain_filter_mode'
:
isWhitelist
,
}));
}
}
style=
{
{
marginBottom
:
8
}
}
>
<
Radio
value=
'whitelist'
>
{
t
(
'白名单'
)
}
</
Radio
>
<
Radio
value=
'blacklist'
>
{
t
(
'黑名单'
)
}
</
Radio
>
</
Radio
.
Group
>
<
TagInput
<
TagInput
value=
{
whitelistDomains
}
value=
{
domainList
}
onChange=
{
(
value
)
=>
{
onChange=
{
(
value
)
=>
{
set
WhitelistDomains
(
value
);
set
DomainList
(
value
);
// 触发Form的onChange事件
// 触发Form的onChange事件
setInputs
(
prev
=>
({
setInputs
(
prev
=>
({
...
prev
,
...
prev
,
'fetch_setting.
whitelist_domains
'
:
value
'fetch_setting.
domain_list
'
:
value
}));
}));
}
}
}
}
placeholder=
{
t
(
'输入域名后回车,如:example.com'
)
}
placeholder=
{
t
(
'输入域名后回车,如:example.com'
)
}
style=
{
{
width
:
'100%'
}
}
style=
{
{
width
:
'100%'
}
}
/>
/>
<
Text
type=
"secondary"
style=
{
{
display
:
'block'
,
marginBottom
:
8
}
}
>
<
Text
type=
"secondary"
style=
{
{
display
:
'block'
,
marginBottom
:
8
}
}
>
{
t
(
'域名
白名单
详细说明'
)
}
{
t
(
'域名
过滤
详细说明'
)
}
</
Text
>
</
Text
>
</
Col
>
</
Col
>
</
Row
>
</
Row
>
...
@@ -730,25 +770,43 @@ const SystemSetting = () => {
...
@@ -730,25 +770,43 @@ const SystemSetting = () => {
style=
{
{
marginTop
:
16
}
}
style=
{
{
marginTop
:
16
}
}
>
>
<
Col
xs=
{
24
}
sm=
{
24
}
md=
{
24
}
lg=
{
24
}
xl=
{
24
}
>
<
Col
xs=
{
24
}
sm=
{
24
}
md=
{
24
}
lg=
{
24
}
xl=
{
24
}
>
<
Text
strong
>
{
t
(
'IP白名单'
)
}
</
Text
>
<
Text
strong
>
{
t
(
ipFilterMode
?
'IP白名单'
:
'IP黑名单'
)
}
</
Text
>
<
Text
type=
"secondary"
style=
{
{
display
:
'block'
,
marginBottom
:
8
}
}
>
<
Text
type=
"secondary"
style=
{
{
display
:
'block'
,
marginBottom
:
8
}
}
>
{
t
(
'支持CIDR格式,如:8.8.8.8, 192.168.1.0/24'
)
}
{
t
(
'支持CIDR格式,如:8.8.8.8, 192.168.1.0/24'
)
}
</
Text
>
</
Text
>
<
Radio
.
Group
type=
'button'
value=
{
ipFilterMode
?
'whitelist'
:
'blacklist'
}
onChange=
{
(
val
)
=>
{
const
isWhitelist
=
val
===
'whitelist'
;
setIpFilterMode
(
isWhitelist
);
setInputs
(
prev
=>
({
...
prev
,
'fetch_setting.ip_filter_mode'
:
isWhitelist
,
}));
}
}
style=
{
{
marginBottom
:
8
}
}
>
<
Radio
value=
'whitelist'
>
{
t
(
'白名单'
)
}
</
Radio
>
<
Radio
value=
'blacklist'
>
{
t
(
'黑名单'
)
}
</
Radio
>
</
Radio
.
Group
>
<
TagInput
<
TagInput
value=
{
whitelistIps
}
value=
{
ipList
}
onChange=
{
(
value
)
=>
{
onChange=
{
(
value
)
=>
{
set
WhitelistIps
(
value
);
set
IpList
(
value
);
// 触发Form的onChange事件
// 触发Form的onChange事件
setInputs
(
prev
=>
({
setInputs
(
prev
=>
({
...
prev
,
...
prev
,
'fetch_setting.
whitelist_ips
'
:
value
'fetch_setting.
ip_list
'
:
value
}));
}));
}
}
}
}
placeholder=
{
t
(
'输入IP地址后回车,如:8.8.8.8'
)
}
placeholder=
{
t
(
'输入IP地址后回车,如:8.8.8.8'
)
}
style=
{
{
width
:
'100%'
}
}
style=
{
{
width
:
'100%'
}
}
/>
/>
<
Text
type=
"secondary"
style=
{
{
display
:
'block'
,
marginBottom
:
8
}
}
>
<
Text
type=
"secondary"
style=
{
{
display
:
'block'
,
marginBottom
:
8
}
}
>
{
t
(
'IP
白名单
详细说明'
)
}
{
t
(
'IP
过滤
详细说明'
)
}
</
Text
>
</
Text
>
</
Col
>
</
Col
>
</
Row
>
</
Row
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment