mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-03-14 01:34:47 +08:00
feat: 同步修改防火墙端口
This commit is contained in:
parent
1c5d01b11c
commit
8902fdc78a
@ -112,6 +112,7 @@ type RootInfo struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Port int64 `json:"port"`
|
||||
HttpsPort int64 `json:"httpsPort"`
|
||||
Password string `json:"password"`
|
||||
UserPassword string `json:"userPassword"`
|
||||
ContainerName string `json:"containerName"`
|
||||
@ -152,6 +153,7 @@ func (a *AppInstallRepo) LoadBaseInfo(key string, name string) (*RootInfo, error
|
||||
info.UserPassword = userPassword
|
||||
}
|
||||
info.Port = int64(appInstall.HttpPort)
|
||||
info.HttpsPort = int64(appInstall.HttpsPort)
|
||||
info.ID = appInstall.ID
|
||||
info.ContainerName = appInstall.ContainerName
|
||||
info.Name = appInstall.Name
|
||||
|
@ -387,6 +387,10 @@ func (a *AppInstallService) ChangeAppPort(req request.PortUpdate) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := OperateFirewallPort([]int{int(appInstall.Port)}, []int{int(req.Port)}); err != nil {
|
||||
global.LOG.Errorf("allow firewall failed, err: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -2,9 +2,12 @@ package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/firewall"
|
||||
fireClient "github.com/1Panel-dev/1Panel/backend/utils/firewall/client"
|
||||
"github.com/jinzhu/copier"
|
||||
@ -101,6 +104,22 @@ func (u *FirewallService) SearchWithPage(req dto.RuleSearch) (int64, interface{}
|
||||
backDatas = datas[start:end]
|
||||
}
|
||||
|
||||
if req.Type == "port" {
|
||||
apps := u.loadPortByApp()
|
||||
for i := 0; i < len(backDatas); i++ {
|
||||
backDatas[i].IsUsed = common.ScanPortWithProtocol(backDatas[i].Port, backDatas[i].Protocol)
|
||||
if backDatas[i].Protocol == "udp" {
|
||||
continue
|
||||
}
|
||||
for _, app := range apps {
|
||||
if app.HttpPort == backDatas[i].Port || app.HttpsPort == backDatas[i].Port {
|
||||
backDatas[i].APPName = app.AppName
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return int64(total), backDatas, nil
|
||||
}
|
||||
|
||||
@ -111,9 +130,24 @@ func (u *FirewallService) OperateFirewall(operation string) error {
|
||||
}
|
||||
switch operation {
|
||||
case "start":
|
||||
return client.Start()
|
||||
if err := client.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
serverPort, err := settingRepo.Get(settingRepo.WithByKey("ServerPort"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := client.Port(fireClient.FireInfo{Port: serverPort.Value, Protocol: "tcp", Strategy: "accept"}, "add"); err != nil {
|
||||
return err
|
||||
}
|
||||
_, _ = cmd.Exec("systemctl restart docker")
|
||||
return nil
|
||||
case "stop":
|
||||
return client.Stop()
|
||||
if err := client.Stop(); err != nil {
|
||||
return err
|
||||
}
|
||||
_, _ = cmd.Exec("systemctl restart docker")
|
||||
return nil
|
||||
case "disablePing":
|
||||
return client.UpdatePingStatus("0")
|
||||
case "enablePing":
|
||||
@ -134,17 +168,48 @@ func (u *FirewallService) OperatePortRule(req dto.PortRuleOperate, reload bool)
|
||||
return u.operatePort(client, req)
|
||||
}
|
||||
}
|
||||
|
||||
if req.Protocol == "tcp/udp" {
|
||||
if client.Name() == "firewalld" && strings.Contains(req.Port, ",") {
|
||||
ports := strings.Split(req.Port, ",")
|
||||
for _, port := range ports {
|
||||
if len(port) == 0 {
|
||||
continue
|
||||
}
|
||||
req.Port = port
|
||||
req.Protocol = "tcp"
|
||||
if err := u.operatePort(client, req); err != nil {
|
||||
return err
|
||||
}
|
||||
req.Protocol = "udp"
|
||||
}
|
||||
if err := u.operatePort(client, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
req.Protocol = "tcp"
|
||||
if err := u.operatePort(client, req); err != nil {
|
||||
return err
|
||||
}
|
||||
req.Protocol = "udp"
|
||||
if err := u.operatePort(client, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if strings.Contains(req.Port, ",") {
|
||||
ports := strings.Split(req.Port, ",")
|
||||
for _, port := range ports {
|
||||
req.Port = port
|
||||
if err := u.operatePort(client, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err := u.operatePort(client, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if reload {
|
||||
return client.Reload()
|
||||
}
|
||||
@ -228,6 +293,26 @@ func (u *FirewallService) BacthOperateRule(req dto.BatchRuleOperate) error {
|
||||
return client.Reload()
|
||||
}
|
||||
|
||||
func OperateFirewallPort(oldPorts, newPorts []int) error {
|
||||
fmt.Printf("old: %v, new: %v \n", oldPorts, newPorts)
|
||||
client, err := firewall.NewFirewallClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, port := range newPorts {
|
||||
|
||||
if err := client.Port(fireClient.FireInfo{Port: strconv.Itoa(port), Protocol: "tcp", Strategy: "accept"}, "add"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, port := range oldPorts {
|
||||
if err := client.Port(fireClient.FireInfo{Port: strconv.Itoa(port), Protocol: "tcp", Strategy: "accept"}, "remove"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return client.Reload()
|
||||
}
|
||||
|
||||
func (u *FirewallService) operatePort(client firewall.FirewallClient, req dto.PortRuleOperate) error {
|
||||
var fireInfo fireClient.FireInfo
|
||||
if err := copier.Copy(&fireInfo, &req); err != nil {
|
||||
@ -246,3 +331,31 @@ func (u *FirewallService) operatePort(client firewall.FirewallClient, req dto.Po
|
||||
}
|
||||
return client.Port(fireInfo, req.Operation)
|
||||
}
|
||||
|
||||
type portOfApp struct {
|
||||
AppName string
|
||||
HttpPort string
|
||||
HttpsPort string
|
||||
}
|
||||
|
||||
func (u *FirewallService) loadPortByApp() []portOfApp {
|
||||
var datas []portOfApp
|
||||
apps, err := appInstallRepo.ListBy()
|
||||
if err != nil {
|
||||
return datas
|
||||
}
|
||||
for i := 0; i < len(apps); i++ {
|
||||
datas = append(datas, portOfApp{
|
||||
AppName: apps[i].App.Key,
|
||||
HttpPort: strconv.Itoa(apps[i].HttpPort),
|
||||
HttpsPort: strconv.Itoa(apps[i].HttpsPort),
|
||||
})
|
||||
}
|
||||
systemPort, err := settingRepo.Get(settingRepo.WithByKey("ServerPort"))
|
||||
if err != nil {
|
||||
return datas
|
||||
}
|
||||
datas = append(datas, portOfApp{AppName: "1panel", HttpPort: systemPort.Value})
|
||||
|
||||
return datas
|
||||
}
|
||||
|
@ -70,7 +70,14 @@ func (u *SettingService) UpdatePort(port uint) error {
|
||||
if common.ScanPort(int(port)) {
|
||||
return buserr.WithDetail(constant.ErrPortInUsed, port, nil)
|
||||
}
|
||||
|
||||
serverPort, err := settingRepo.Get(settingRepo.WithByKey("ServerPort"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
portValue, _ := strconv.Atoi(serverPort.Value)
|
||||
if err := OperateFirewallPort([]int{portValue}, []int{int(port)}); err != nil {
|
||||
global.LOG.Errorf("set system firewall ports failed, err: %v", err)
|
||||
}
|
||||
if err := settingRepo.Update("ServerPort", strconv.Itoa(int(port))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||
)
|
||||
|
||||
func CompareVersion(version1 string, version2 string) bool {
|
||||
@ -92,6 +94,27 @@ func ScanPort(port int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func ScanPortWithProtocol(port, Protocol string) bool {
|
||||
command := "netstat -ntpl"
|
||||
if Protocol == "udp" {
|
||||
command = "netstat -nupl"
|
||||
}
|
||||
stdout, err := cmd.Execf("%s | awk '{print $4}' ", command)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
lines := strings.Split(stdout, "\n")
|
||||
if len(lines) == 0 {
|
||||
return false
|
||||
}
|
||||
for _, line := range lines {
|
||||
if strings.HasSuffix(line, ":"+port) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func ExistWithStrArray(str string, arr []string) bool {
|
||||
for _, a := range arr {
|
||||
if strings.Contains(a, str) {
|
||||
|
@ -20,7 +20,10 @@ func (f *Firewall) Name() string {
|
||||
|
||||
func (f *Firewall) Status() (string, error) {
|
||||
stdout, _ := cmd.Exec("firewall-cmd --state")
|
||||
return strings.ReplaceAll(stdout, "\n", ""), nil
|
||||
if stdout == "running\n" {
|
||||
return "running", nil
|
||||
}
|
||||
return "not running", nil
|
||||
}
|
||||
|
||||
func (f *Firewall) Version() (string, error) {
|
||||
@ -83,6 +86,9 @@ func (f *Firewall) ListPort() ([]FireInfo, error) {
|
||||
ports := strings.Split(strings.ReplaceAll(stdout, "\n", ""), " ")
|
||||
var datas []FireInfo
|
||||
for _, port := range ports {
|
||||
if len(port) == 0 {
|
||||
continue
|
||||
}
|
||||
var itemPort FireInfo
|
||||
if strings.Contains(port, "/") {
|
||||
itemPort.Port = strings.Split(port, "/")[0]
|
||||
@ -121,7 +127,7 @@ func (f *Firewall) ListAddress() ([]FireInfo, error) {
|
||||
continue
|
||||
}
|
||||
itemRule := f.loadInfo(rule)
|
||||
if len(itemRule.Port) == 0 {
|
||||
if len(itemRule.Port) == 0 && len(itemRule.Address) != 0 {
|
||||
datas = append(datas, itemRule)
|
||||
}
|
||||
}
|
||||
@ -137,7 +143,11 @@ func (f *Firewall) Port(port FireInfo, operation string) error {
|
||||
}
|
||||
|
||||
func (f *Firewall) RichRules(rule FireInfo, operation string) error {
|
||||
ruleStr := "rule family=ipv4 "
|
||||
ruleStr := ""
|
||||
if strings.Contains(rule.Address, "-") {
|
||||
ruleStr = fmt.Sprintf("rule source ipset=%s %s", rule.Address, rule.Strategy)
|
||||
} else {
|
||||
ruleStr = "rule family=ipv4 "
|
||||
if len(rule.Address) != 0 {
|
||||
ruleStr += fmt.Sprintf("source address=%s ", rule.Address)
|
||||
}
|
||||
@ -148,7 +158,7 @@ func (f *Firewall) RichRules(rule FireInfo, operation string) error {
|
||||
ruleStr += fmt.Sprintf("protocol=%s ", rule.Protocol)
|
||||
}
|
||||
ruleStr += rule.Strategy
|
||||
|
||||
}
|
||||
stdout, err := cmd.Execf("firewall-cmd --zone=public --%s-rich-rule '%s' --permanent", operation, ruleStr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s rich rules failed, err: %s", operation, stdout)
|
||||
@ -176,13 +186,15 @@ func (f *Firewall) loadInfo(line string) FireInfo {
|
||||
switch {
|
||||
case strings.Contains(item, "family="):
|
||||
itemRule.Family = strings.ReplaceAll(item, "family=", "")
|
||||
case strings.Contains(item, "ipset="):
|
||||
itemRule.Address = strings.ReplaceAll(item, "ipset=", "")
|
||||
case strings.Contains(item, "address="):
|
||||
itemRule.Address = strings.ReplaceAll(item, "address=", "")
|
||||
case strings.Contains(item, "port="):
|
||||
itemRule.Port = strings.ReplaceAll(item, "port=", "")
|
||||
case strings.Contains(item, "protocol="):
|
||||
itemRule.Protocol = strings.ReplaceAll(item, "protocol=", "")
|
||||
case item == "accept" || item == "drop":
|
||||
case item == "accept" || item == "drop" || item == "reject":
|
||||
itemRule.Strategy = item
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/ssh"
|
||||
)
|
||||
|
||||
func TestFire(t *testing.T) {
|
||||
ConnInfo := ssh.ConnInfo{
|
||||
Addr: "172.16.10.234",
|
||||
User: "ubuntu",
|
||||
AuthMode: "password",
|
||||
Port: 22,
|
||||
}
|
||||
output, err := ConnInfo.Run("sudo ufw status verbose")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
lines := strings.Split(string(output), "\n")
|
||||
var datas []FireInfo
|
||||
isStart := false
|
||||
for _, line := range lines {
|
||||
if strings.HasPrefix(line, "--") {
|
||||
isStart = true
|
||||
continue
|
||||
}
|
||||
if !isStart {
|
||||
continue
|
||||
}
|
||||
|
||||
}
|
||||
fmt.Println(datas)
|
||||
}
|
@ -6,6 +6,9 @@ type FireInfo struct {
|
||||
Port string `json:"port"`
|
||||
Protocol string `json:"protocol"` // tcp udp tcp/udp
|
||||
Strategy string `json:"strategy"` // accept drop
|
||||
|
||||
APPName string `json:"appName"`
|
||||
IsUsed bool `json:"isUsed"`
|
||||
}
|
||||
|
||||
type Forward struct {
|
||||
|
@ -85,6 +85,11 @@ func (f *Ufw) UpdatePingStatus(enabel string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
stdout, err := cmd.Exec("sudo ufw reload")
|
||||
if err != nil {
|
||||
return fmt.Errorf("reload ufw setting failed, err: %v", stdout)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,8 @@ export namespace Host {
|
||||
port: string;
|
||||
protocol: string;
|
||||
strategy: string;
|
||||
appName: string;
|
||||
isUsed: boolean;
|
||||
}
|
||||
export interface RulePort {
|
||||
operation: string;
|
||||
|
@ -1185,19 +1185,33 @@ const message = {
|
||||
cookieBlockList: 'Cookie Blacklist',
|
||||
|
||||
firewall: 'Firewall',
|
||||
used: 'Used',
|
||||
unUsed: 'Unused',
|
||||
firewallHelper: '{0} System firewall',
|
||||
firewallNotStart: 'The firewall service is not enabled at present, please enable it first!',
|
||||
stopFirewallHelper:
|
||||
'If the firewall is disabled, the server loses security protection. Do you want to continue?',
|
||||
'After the system firewall is disabled, the server loses security protection. Do you want to continue?',
|
||||
startFirewallHelper:
|
||||
'After the firewall is enabled, the current server security can be better protected. Do you want to continue?',
|
||||
'After the firewall is enabled, the server security can be better protected. Do you want to continue?',
|
||||
noPing: 'Disable ping',
|
||||
noPingHelper:
|
||||
'If the ping function is disabled, the server cannot be pinged. Do you want to continue the operation?',
|
||||
noPingTitle: 'Disable ping',
|
||||
noPingHelper: 'If the ping function is disabled, the server cannot be pinged. Do you want to continue?',
|
||||
onPingHelper: 'If you disable ping, hackers may discover your server. Do you want to continue?',
|
||||
protocol: 'Protocol',
|
||||
port: 'Port',
|
||||
changeStrategy: 'Change the {0} strategy',
|
||||
changeStrategyIPHelper1:
|
||||
'Change the IP address strategy to [deny]. After the IP address is set, access to the server is prohibited. Do you want to continue?',
|
||||
changeStrategyIPHelper2:
|
||||
'Change the IP address strategy to [allow]. After the IP address is set, normal access is restored. Do you want to continue?',
|
||||
changeStrategyPortHelper1:
|
||||
'Change the port policy to [drop]. After the port policy is set, external access is denied. Do you want to continue?',
|
||||
changeStrategyPortHelper2:
|
||||
'Change the port policy to [accept]. After the policy is set, normal port access will be restored. Do you want to continue?',
|
||||
stop: 'Stop',
|
||||
portFormatError: 'Please enter the correct port information!',
|
||||
portHelper1: 'Multiple ports, such as 8080 and 8081',
|
||||
portHelper2: 'Range port, such as 8080-8089',
|
||||
changeStrategyHelper:
|
||||
'Change [{1}] {0} strategy to [{2}]. After setting, {0} will access {2} externally. Do you want to continue?',
|
||||
portHelper: 'Multiple ports can be entered, such as 80,81, or range ports, such as 80-88',
|
||||
@ -1209,9 +1223,10 @@ const message = {
|
||||
address: 'Specified IP',
|
||||
allow: 'Allow',
|
||||
deny: 'Deny',
|
||||
addressHelper1: 'Support for multiple IP, such as 172.16.10.11 172.16.10.99',
|
||||
addressHelper2: 'You can enter an IP address segment, for example, 172.16.10.0/24',
|
||||
addressHelper3: 'You can enter an IP address range, such as 172.16.10.11-172.16.10.99',
|
||||
addressFormatError: 'Please enter a valid ip address!',
|
||||
addressHelper1: 'Multiple IP please separated with ",", such as 172.16.10.11, 172.16.10.99',
|
||||
addressHelper2: 'IP segment, such as 172.16.10.0/24',
|
||||
addressHelper3: 'IP address range, such as 172.16.10.11-172.16.10.99',
|
||||
allIP: 'All IP',
|
||||
portRule: 'Port rule',
|
||||
ipRule: 'IP rule',
|
||||
|
@ -807,6 +807,8 @@ const message = {
|
||||
LOCAL: '服务器磁盘',
|
||||
currentPath: '当前路径',
|
||||
OSS: '阿里云 OSS',
|
||||
COS: '腾讯云 cos browser',
|
||||
KODO: '七牛云 Kodo',
|
||||
S3: '亚马逊 S3 云存储',
|
||||
MINIO: 'MINIO',
|
||||
SFTP: 'SFTP',
|
||||
@ -1184,18 +1186,27 @@ const message = {
|
||||
cookieBlockList: 'Cookie 黑名单',
|
||||
|
||||
firewall: '防火墙',
|
||||
used: '已使用',
|
||||
unUsed: '未使用',
|
||||
firewallHelper: '{0}系统防火墙',
|
||||
firewallNotStart: '当前未开启防火墙服务,请先开启!',
|
||||
stopFirewallHelper: '停用系统防火墙,服务器将失去安全防护,是否继续操作?',
|
||||
startFirewallHelper: '启用系统防火墙后,可以更好的防护当前的服务器安全,是否继续操作?',
|
||||
stopFirewallHelper: '系统防火墙关闭后,服务器将失去安全防护,是否继续?',
|
||||
startFirewallHelper: '系统防火墙开启后,可以更好的防护服务器安全,是否继续?',
|
||||
noPing: '禁 ping',
|
||||
noPingHelper: '禁 ping 后不影响服务器正常使用,但无法 ping 通服务器,是否继续操作?',
|
||||
onPingHelper: '解除禁 ping 状态可能会被黑客发现您的服务器,是否继续操作?',
|
||||
noPingTitle: '是否禁 ping',
|
||||
noPingHelper: '禁 ping 后将无法 ping 通服务器,是否继续?',
|
||||
onPingHelper: '解除禁 ping 后您的服务器可能会被黑客发现,是否继续?',
|
||||
protocol: '协议',
|
||||
port: '端口',
|
||||
changeStrategy: '修改{0}策略',
|
||||
changeStrategyHelper: '修改 [{1}] {0}策略为 [{2}],设置后该{0}将{2}外部访问,是否继续操作?',
|
||||
portHelper: '支持输入多个端口,如 80,81 或者范围端口,如 80-88',
|
||||
changeStrategyIPHelper1: 'IP 策略修改为【屏蔽】,设置后该 IP 将禁止访问服务器,是否继续?',
|
||||
changeStrategyIPHelper2: 'IP 策略修改为【放行】,设置后该 IP 将恢复正常访问,是否继续?',
|
||||
changeStrategyPortHelper1: '端口策略修改为【拒绝】,设置后端口将拒绝外部访问,是否继续?',
|
||||
changeStrategyPortHelper2: '端口策略为【允许】,设置后端口将恢复正常访问,是否继续?',
|
||||
stop: '禁止',
|
||||
portFormatError: '请输入正确的端口信息!',
|
||||
portHelper1: '多个端口,如:8080,8081',
|
||||
portHelper2: '范围端口,如:8080-8089',
|
||||
strategy: '策略',
|
||||
accept: '允许',
|
||||
drop: '拒绝',
|
||||
@ -1204,9 +1215,10 @@ const message = {
|
||||
address: '指定 IP',
|
||||
allow: '放行',
|
||||
deny: '屏蔽',
|
||||
addressHelper1: '支持输入多个 IP ,如 172.16.10.11,172.16.10.99',
|
||||
addressHelper2: '支持输入 IP 段,如 172.16.10.0/24',
|
||||
addressHelper3: '支持输入 IP 范围,如 172.16.10.11-172.16.10.99',
|
||||
addressFormatError: '请输入合法的 ip 地址!',
|
||||
addressHelper1: '多个 IP 请用 "," 隔开:172.16.10.11,172.16.10.99',
|
||||
addressHelper2: 'IP 段:172.16.0.0/24',
|
||||
addressHelper3: 'IP 范围:172.16.10.10-172.16.10.19(暂不支持跨网段范围)',
|
||||
allIP: '所有 IP',
|
||||
portRule: '端口规则',
|
||||
ipRule: 'IP 规则',
|
||||
|
@ -167,6 +167,15 @@ export function checkIp(value: string): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
export function checkPort(value: string): boolean {
|
||||
const reg = /^([0-9]|[1-9]\d{1,3}|[1-5]\d{4}|6[0-5]{2}[0-3][0-5])$/;
|
||||
if (!reg.test(value) && value !== '') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function getProvider(provider: string): string {
|
||||
switch (provider) {
|
||||
case 'dnsAccount':
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div v-loading="loading" style="position: relative">
|
||||
<FireRouter />
|
||||
<FireStatus ref="fireStatuRef" @search="search" v-model:loading="loading" v-model:status="fireStatus" />
|
||||
|
||||
@ -108,6 +108,12 @@ const paginationConfig = reactive({
|
||||
});
|
||||
|
||||
const search = async () => {
|
||||
if (fireStatus.value !== 'running') {
|
||||
loading.value = false;
|
||||
data.value = [];
|
||||
paginationConfig.total = 0;
|
||||
return;
|
||||
}
|
||||
let params = {
|
||||
type: activeTag.value,
|
||||
info: searchName.value,
|
||||
@ -141,15 +147,14 @@ const onOpenDialog = async (
|
||||
};
|
||||
|
||||
const onChangeStatus = async (row: Host.RuleInfo, status: string) => {
|
||||
let operation = status === 'accept' ? i18n.global.t('firewall.allow') : i18n.global.t('firewall.deny');
|
||||
ElMessageBox.confirm(
|
||||
i18n.global.t('firewall.changeStrategyHelper', ['IP', row.address, operation]),
|
||||
i18n.global.t('firewall.changeStrategy', ['IP']),
|
||||
{
|
||||
let operation =
|
||||
status === 'accept'
|
||||
? i18n.global.t('firewall.changeStrategyIPHelper2')
|
||||
: i18n.global.t('firewall.changeStrategyIPHelper1');
|
||||
ElMessageBox.confirm(operation, i18n.global.t('firewall.changeStrategy', [' IP ']), {
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
},
|
||||
).then(async () => {
|
||||
}).then(async () => {
|
||||
let params = {
|
||||
oldRule: {
|
||||
operation: 'remove',
|
||||
|
@ -9,10 +9,11 @@
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('firewall.address')" prop="address">
|
||||
<el-input
|
||||
:disabled="dialogData.title === 'edit'"
|
||||
:autosize="{ minRows: 3, maxRows: 6 }"
|
||||
type="textarea"
|
||||
clearable
|
||||
v-model="dialogData.rowData!.address"
|
||||
v-model.trim="dialogData.rowData!.address"
|
||||
/>
|
||||
<span class="input-help">{{ $t('firewall.addressHelper1') }}</span>
|
||||
<span class="input-help">{{ $t('firewall.addressHelper2') }}</span>
|
||||
@ -45,10 +46,10 @@ import { Rules } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
import { ElForm } from 'element-plus';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||
import { Host } from '@/api/interface/host';
|
||||
import { operateIPRule, updateAddrRule } from '@/api/modules/host';
|
||||
import { deepCopy } from '@/utils/util';
|
||||
import { checkIp, deepCopy } from '@/utils/util';
|
||||
|
||||
const loading = ref();
|
||||
const oldRule = ref<Host.RuleIP>();
|
||||
@ -88,9 +89,25 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
loading.value = true;
|
||||
dialogData.value.rowData.operation = 'add';
|
||||
if (!dialogData.value.rowData) return;
|
||||
let ips = [];
|
||||
if (dialogData.value.rowData.address.indexOf('-') !== -1) {
|
||||
ips = dialogData.value.rowData.address.split('-');
|
||||
} else if (dialogData.value.rowData.address.indexOf(',') !== -1) {
|
||||
ips = dialogData.value.rowData.address.split(',');
|
||||
} else if (dialogData.value.rowData.address.indexOf('/') !== -1) {
|
||||
ips.push(dialogData.value.rowData.address.split('/')[0]);
|
||||
} else {
|
||||
ips.push(dialogData.value.rowData.address);
|
||||
}
|
||||
for (const ip of ips) {
|
||||
if (checkIp(ip)) {
|
||||
MsgError(i18n.global.t('firewall.addressFormatError'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
loading.value = true;
|
||||
if (dialogData.value.title === 'create') {
|
||||
await operateIPRule(dialogData.value.rowData)
|
||||
.then(() => {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div v-loading="loading">
|
||||
<div v-loading="loading" style="position: relative">
|
||||
<FireRouter />
|
||||
|
||||
<FireStatus ref="fireStatuRef" @search="search" v-model:loading="loading" v-model:status="fireStatus" />
|
||||
@ -42,13 +42,24 @@
|
||||
@search="search"
|
||||
:data="data"
|
||||
>
|
||||
<el-table-column type="selection" fix />
|
||||
<el-table-column type="selection" :selectable="selectable" fix />
|
||||
<el-table-column :label="$t('firewall.protocol')" :min-width="90" prop="protocol" />
|
||||
<el-table-column :label="$t('firewall.port')" :min-width="120" prop="port" />
|
||||
<el-table-column :label="$t('commons.table.status')" :min-width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag type="info" v-if="row.isUsed">
|
||||
{{
|
||||
row.appName ? $t('firewall.used') + ' ( ' + row.appName + ' )' : $t('firewall.used')
|
||||
}}
|
||||
</el-tag>
|
||||
<el-tag type="success" v-else>{{ $t('firewall.unUsed') }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :min-width="80" :label="$t('firewall.strategy')" prop="strategy">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
v-if="row.strategy === 'accept'"
|
||||
:disabled="row.appName === '1panel'"
|
||||
@click="onChangeStatus(row, 'drop')"
|
||||
link
|
||||
type="success"
|
||||
@ -111,6 +122,12 @@ const paginationConfig = reactive({
|
||||
});
|
||||
|
||||
const search = async () => {
|
||||
if (fireStatus.value !== 'running') {
|
||||
loading.value = false;
|
||||
data.value = [];
|
||||
paginationConfig.total = 0;
|
||||
return;
|
||||
}
|
||||
let params = {
|
||||
type: activeTag.value,
|
||||
info: searchName.value,
|
||||
@ -146,15 +163,14 @@ const onOpenDialog = async (
|
||||
};
|
||||
|
||||
const onChangeStatus = async (row: Host.RuleInfo, status: string) => {
|
||||
let operation = i18n.global.t('firewall.' + status);
|
||||
ElMessageBox.confirm(
|
||||
i18n.global.t('firewall.changeStrategyHelper', [i18n.global.t('firewall.port'), row.port, operation]),
|
||||
i18n.global.t('firewall.changeStrategy', [i18n.global.t('firewall.port')]),
|
||||
{
|
||||
let operation =
|
||||
status === 'accept'
|
||||
? i18n.global.t('firewall.changeStrategyPortHelper2')
|
||||
: i18n.global.t('firewall.changeStrategyPortHelper1');
|
||||
ElMessageBox.confirm(operation, i18n.global.t('firewall.changeStrategy', [i18n.global.t('firewall.port')]), {
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
},
|
||||
).then(async () => {
|
||||
}).then(async () => {
|
||||
let params = {
|
||||
oldRule: {
|
||||
operation: 'remove',
|
||||
@ -227,18 +243,28 @@ const onDelete = async (row: Host.RuleInfo | null) => {
|
||||
});
|
||||
};
|
||||
|
||||
function selectable(row) {
|
||||
return row.appName !== '1panel';
|
||||
}
|
||||
|
||||
const buttons = [
|
||||
{
|
||||
label: i18n.global.t('commons.button.edit'),
|
||||
click: (row: Host.RulePort) => {
|
||||
onOpenDialog('edit', row);
|
||||
},
|
||||
disabled: (row: any) => {
|
||||
return row.appName === '1panel';
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('commons.button.delete'),
|
||||
click: (row: Host.RuleInfo) => {
|
||||
onDelete(row);
|
||||
},
|
||||
disabled: (row: any) => {
|
||||
return row.appName === '1panel';
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -16,8 +16,13 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('firewall.port')" prop="port">
|
||||
<el-input clearable v-model.trim="dialogData.rowData!.port" />
|
||||
<span class="input-help">{{ $t('firewall.portHelper') }}</span>
|
||||
<el-input
|
||||
:disabled="dialogData.title === 'edit'"
|
||||
clearable
|
||||
v-model.trim="dialogData.rowData!.port"
|
||||
/>
|
||||
<span class="input-help">{{ $t('firewall.portHelper1') }}</span>
|
||||
<span class="input-help">{{ $t('firewall.portHelper2') }}</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('firewall.source')" prop="source">
|
||||
@ -62,10 +67,10 @@ import { Rules } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
import { ElForm } from 'element-plus';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||
import { Host } from '@/api/interface/host';
|
||||
import { operatePortRule, updatePortRule } from '@/api/modules/host';
|
||||
import { deepCopy } from '@/utils/util';
|
||||
import { checkPort, deepCopy } from '@/utils/util';
|
||||
|
||||
const loading = ref();
|
||||
const oldRule = ref<Host.RulePort>();
|
||||
@ -102,7 +107,7 @@ const handleClose = () => {
|
||||
const rules = reactive({
|
||||
protocol: [Rules.requiredSelect],
|
||||
port: [Rules.requiredInput],
|
||||
address: [Rules.requiredInput],
|
||||
address: [Rules.ip],
|
||||
});
|
||||
|
||||
type FormInstance = InstanceType<typeof ElForm>;
|
||||
@ -114,6 +119,23 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||
if (!valid) return;
|
||||
dialogData.value.rowData.operation = 'add';
|
||||
if (!dialogData.value.rowData) return;
|
||||
if (dialogData.value.rowData.source === 'anyWhere') {
|
||||
dialogData.value.rowData.address = '';
|
||||
}
|
||||
let ports = [];
|
||||
if (dialogData.value.rowData.port.indexOf('-') !== -1) {
|
||||
ports = dialogData.value.rowData.port.split('-');
|
||||
} else if (dialogData.value.rowData.port.indexOf(',') !== -1) {
|
||||
ports = dialogData.value.rowData.port.split(',');
|
||||
} else {
|
||||
ports.push(dialogData.value.rowData.port);
|
||||
}
|
||||
for (const port of ports) {
|
||||
if (checkPort(port)) {
|
||||
MsgError(i18n.global.t('firewall.portFormatError'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
loading.value = true;
|
||||
if (dialogData.value.title === 'create') {
|
||||
await operatePortRule(dialogData.value.rowData)
|
||||
|
@ -16,6 +16,12 @@
|
||||
<el-button type="primary" @click="onOperate('stop')" link>
|
||||
{{ $t('commons.button.stop') }}
|
||||
</el-button>
|
||||
</span>
|
||||
<span v-if="baseInfo.status === 'not running'" class="buttons">
|
||||
<el-button type="primary" @click="onOperate('start')" link>
|
||||
{{ $t('commons.button.start') }}
|
||||
</el-button>
|
||||
</span>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button type="primary" link>{{ $t('firewall.noPing') }}</el-button>
|
||||
<el-switch
|
||||
@ -25,13 +31,6 @@
|
||||
@change="onPingOperate(baseInfo.pingStatus)"
|
||||
v-model="onPing"
|
||||
/>
|
||||
</span>
|
||||
|
||||
<span v-if="baseInfo.status === 'not running'" class="buttons">
|
||||
<el-button type="primary" @click="onOperate('start')" link>
|
||||
{{ $t('commons.button.start') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
@ -42,11 +41,12 @@
|
||||
import { Host } from '@/api/interface/host';
|
||||
import { loadFireBaseInfo, operateFire } from '@/api/modules/host';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const baseInfo = ref<Host.FirewallBase>({ status: '', name: '', version: '', pingStatus: '' });
|
||||
const onPing = ref();
|
||||
const onPing = ref('Disable');
|
||||
|
||||
const acceptParams = (): void => {
|
||||
loadBaseInfo(true);
|
||||
@ -59,7 +59,7 @@ const loadBaseInfo = async (search: boolean) => {
|
||||
baseInfo.value = res.data;
|
||||
onPing.value = baseInfo.value.pingStatus;
|
||||
emit('update:status', baseInfo.value.status);
|
||||
if (baseInfo.value.status === 'running' && search) {
|
||||
if (search) {
|
||||
emit('search');
|
||||
} else {
|
||||
emit('update:loading', false);
|
||||
@ -81,6 +81,7 @@ const onOperate = async (operation: string) => {
|
||||
emit('update:status', 'running');
|
||||
await operateFire(operation)
|
||||
.then(() => {
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
loadBaseInfo(true);
|
||||
})
|
||||
.catch(() => {
|
||||
@ -92,7 +93,7 @@ const onOperate = async (operation: string) => {
|
||||
const onPingOperate = async (operation: string) => {
|
||||
let operationHelper =
|
||||
operation === 'Enabel' ? i18n.global.t('firewall.noPingHelper') : i18n.global.t('firewall.onPingHelper');
|
||||
ElMessageBox.confirm(operationHelper, i18n.global.t('firewall.noPing'), {
|
||||
ElMessageBox.confirm(operationHelper, i18n.global.t('firewall.noPingTitle'), {
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
})
|
||||
@ -102,6 +103,7 @@ const onPingOperate = async (operation: string) => {
|
||||
operation = operation === 'Disable' ? 'enablePing' : 'disablePing';
|
||||
await operateFire(operation)
|
||||
.then(() => {
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
loadBaseInfo(false);
|
||||
})
|
||||
.catch(() => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user