fix: docker 配置增加 iptables (#535)

This commit is contained in:
ssongliu 2023-04-07 17:44:15 +08:00 committed by GitHub
parent 74b6af64e9
commit dbe70ecc28
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 62 additions and 8 deletions

View file

@ -10,6 +10,7 @@ type DaemonJsonConf struct {
Mirrors []string `json:"registryMirrors"` Mirrors []string `json:"registryMirrors"`
Registries []string `json:"insecureRegistries"` Registries []string `json:"insecureRegistries"`
LiveRestore bool `json:"liveRestore"` LiveRestore bool `json:"liveRestore"`
IPTables bool `json:"iptables"`
CgroupDriver string `json:"cgroupDriver"` CgroupDriver string `json:"cgroupDriver"`
} }

View file

@ -34,6 +34,7 @@ type daemonJsonItem struct {
Mirrors []string `json:"registry-mirrors"` Mirrors []string `json:"registry-mirrors"`
Registries []string `json:"insecure-registries"` Registries []string `json:"insecure-registries"`
LiveRestore bool `json:"live-restore"` LiveRestore bool `json:"live-restore"`
IPTables bool `json:"iptables"`
ExecOpts []string `json:"exec-opts"` ExecOpts []string `json:"exec-opts"`
} }
@ -63,23 +64,26 @@ func (u *DockerService) LoadDockerConf() *dto.DaemonJsonConf {
} }
} }
if _, err := os.Stat(constant.DaemonJsonPath); err != nil { if _, err := os.Stat(constant.DaemonJsonPath); err != nil {
return &dto.DaemonJsonConf{Status: status, Version: version} return &dto.DaemonJsonConf{Status: status, IPTables: true, Version: version}
} }
file, err := os.ReadFile(constant.DaemonJsonPath) file, err := os.ReadFile(constant.DaemonJsonPath)
if err != nil { if err != nil {
return &dto.DaemonJsonConf{Status: status, Version: version} return &dto.DaemonJsonConf{Status: status, IPTables: true, Version: version}
} }
var conf daemonJsonItem var conf daemonJsonItem
deamonMap := make(map[string]interface{}) deamonMap := make(map[string]interface{})
if err := json.Unmarshal(file, &deamonMap); err != nil { if err := json.Unmarshal(file, &deamonMap); err != nil {
return &dto.DaemonJsonConf{Status: status, Version: version} return &dto.DaemonJsonConf{Status: status, IPTables: true, Version: version}
} }
arr, err := json.Marshal(deamonMap) arr, err := json.Marshal(deamonMap)
if err != nil { if err != nil {
return &dto.DaemonJsonConf{Status: status, Version: version} return &dto.DaemonJsonConf{Status: status, IPTables: true, Version: version}
} }
if err := json.Unmarshal(arr, &conf); err != nil { if err := json.Unmarshal(arr, &conf); err != nil {
return &dto.DaemonJsonConf{Status: status, Version: version} return &dto.DaemonJsonConf{Status: status, IPTables: true, Version: version}
}
if _, ok := deamonMap["iptables"]; !ok {
conf.IPTables = true
} }
driver := "cgroupfs" driver := "cgroupfs"
for _, opt := range conf.ExecOpts { for _, opt := range conf.ExecOpts {
@ -93,6 +97,7 @@ func (u *DockerService) LoadDockerConf() *dto.DaemonJsonConf {
Version: version, Version: version,
Mirrors: conf.Mirrors, Mirrors: conf.Mirrors,
Registries: conf.Registries, Registries: conf.Registries,
IPTables: conf.IPTables,
LiveRestore: conf.LiveRestore, LiveRestore: conf.LiveRestore,
CgroupDriver: driver, CgroupDriver: driver,
} }
@ -130,6 +135,11 @@ func (u *DockerService) UpdateConf(req dto.DaemonJsonConf) error {
} else { } else {
deamonMap["live-restore"] = req.LiveRestore deamonMap["live-restore"] = req.LiveRestore
} }
if req.IPTables {
delete(deamonMap, "iptables")
} else {
deamonMap["live-restore"] = false
}
if opts, ok := deamonMap["exec-opts"]; ok { if opts, ok := deamonMap["exec-opts"]; ok {
if optsValue, isArray := opts.([]interface{}); isArray { if optsValue, isArray := opts.([]interface{}); isArray {
for i := 0; i < len(optsValue); i++ { for i := 0; i < len(optsValue); i++ {
@ -162,6 +172,12 @@ func (u *DockerService) UpdateConf(req dto.DaemonJsonConf) error {
} }
func (u *DockerService) UpdateConfByFile(req dto.DaemonJsonUpdateByFile) error { func (u *DockerService) UpdateConfByFile(req dto.DaemonJsonUpdateByFile) error {
if _, err := os.Stat(constant.DaemonJsonPath); err != nil && os.IsNotExist(err) {
if err = os.MkdirAll(path.Dir(constant.DaemonJsonPath), os.ModePerm); err != nil {
return err
}
_, _ = os.Create(constant.DaemonJsonPath)
}
file, err := os.OpenFile(constant.DaemonJsonPath, os.O_WRONLY|os.O_TRUNC, 0640) file, err := os.OpenFile(constant.DaemonJsonPath, os.O_WRONLY|os.O_TRUNC, 0640)
if err != nil { if err != nil {
return err return err

View file

@ -252,6 +252,7 @@ export namespace Container {
registryMirrors: Array<string>; registryMirrors: Array<string>;
insecureRegistries: Array<string>; insecureRegistries: Array<string>;
liveRestore: boolean; liveRestore: boolean;
iptables: boolean;
cgroupDriver: string; cgroupDriver: string;
} }
} }

View file

@ -1222,10 +1222,13 @@ const message = {
cookieBlockList: 'Cookie Blacklist', cookieBlockList: 'Cookie Blacklist',
firewall: 'Firewall', firewall: 'Firewall',
dockerHelper:
'Linux firewall {0} cannot disable Docker port mapping, you need to disable iptables in Docker configuration.',
quickJump: 'Quick jump',
used: 'Used', used: 'Used',
unUsed: 'Unused', unUsed: 'Unused',
firewallHelper: '{0} System firewall', firewallHelper: '{0} System firewall',
firewallNotStart: 'The firewall service is not enabled at present, please enable it first!', firewallNotStart: 'The system firewall is not enabled at present, please enable it first!',
stopFirewallHelper: stopFirewallHelper:
'After the system 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: startFirewallHelper:

View file

@ -1218,10 +1218,12 @@ const message = {
cookieBlockList: 'Cookie 黑名单', cookieBlockList: 'Cookie 黑名单',
firewall: '防火墙', firewall: '防火墙',
dockerHelper: 'Linux 防火墙 {0} 无法禁用 Docker 端口映射需要在 Docker 配置中禁用 iptables',
quickJump: '快速跳转',
used: '已使用', used: '已使用',
unUsed: '未使用', unUsed: '未使用',
firewallHelper: '{0}系统防火墙', firewallHelper: '{0}系统防火墙',
firewallNotStart: '当前未开启防火墙服务请先开启', firewallNotStart: '当前未开启系统防火墙请先开启',
stopFirewallHelper: '系统防火墙关闭后服务器将失去安全防护是否继续', stopFirewallHelper: '系统防火墙关闭后服务器将失去安全防护是否继续',
startFirewallHelper: '系统防火墙开启后可以更好的防护服务器安全是否继续', startFirewallHelper: '系统防火墙开启后可以更好的防护服务器安全是否继续',
noPing: ' ping', noPing: ' ping',

View file

@ -62,6 +62,9 @@
v-model="form.registries" v-model="form.registries"
/> />
</el-form-item> </el-form-item>
<el-form-item label="iptables" prop="iptables">
<el-switch v-model="form.iptables"></el-switch>
</el-form-item>
<el-form-item label="live-restore" prop="liveRestore"> <el-form-item label="live-restore" prop="liveRestore">
<el-switch v-model="form.liveRestore"></el-switch> <el-switch v-model="form.liveRestore"></el-switch>
<span class="input-help">{{ $t('container.liveHelper') }}</span> <span class="input-help">{{ $t('container.liveHelper') }}</span>
@ -153,6 +156,7 @@ const form = reactive({
mirrors: '', mirrors: '',
registries: '', registries: '',
liveRestore: false, liveRestore: false,
iptables: true,
cgroupDriver: '', cgroupDriver: '',
}); });
@ -255,6 +259,7 @@ const onSubmitSave = async () => {
return el !== null && el !== '' && el !== undefined; return el !== null && el !== '' && el !== undefined;
}), }),
liveRestore: form.liveRestore, liveRestore: form.liveRestore,
iptables: form.iptables,
cgroupDriver: form.cgroupDriver, cgroupDriver: form.cgroupDriver,
}; };
loading.value = true; loading.value = true;
@ -293,6 +298,7 @@ const search = async () => {
form.version = res.data.version; form.version = res.data.version;
form.cgroupDriver = res.data.cgroupDriver; form.cgroupDriver = res.data.cgroupDriver;
form.liveRestore = res.data.liveRestore; form.liveRestore = res.data.liveRestore;
form.iptables = res.data.iptables;
form.mirrors = res.data.registryMirrors ? res.data.registryMirrors.join('\n') : ''; form.mirrors = res.data.registryMirrors ? res.data.registryMirrors.join('\n') : '';
form.registries = res.data.insecureRegistries ? res.data.insecureRegistries.join('\n') : ''; form.registries = res.data.insecureRegistries ? res.data.insecureRegistries.join('\n') : '';
}; };

View file

@ -8,6 +8,7 @@
v-model:loading="loading" v-model:loading="loading"
v-model:mask-show="maskShow" v-model:mask-show="maskShow"
v-model:status="fireStatus" v-model:status="fireStatus"
v-model:name="fireName"
/> />
<el-card v-if="fireStatus != 'running' && maskShow" class="mask-prompt"> <el-card v-if="fireStatus != 'running' && maskShow" class="mask-prompt">
@ -15,6 +16,23 @@
</el-card> </el-card>
<LayoutContent :title="$t('firewall.portRule')" :class="{ mask: fireStatus != 'running' }"> <LayoutContent :title="$t('firewall.portRule')" :class="{ mask: fireStatus != 'running' }">
<template #prompt>
<el-alert type="info" :closable="false">
<template #default>
<span>
<span>{{ $t('firewall.dockerHelper', [fireName]) }}</span>
<el-link
style="font-size: 12px; margin-left: 5px"
icon="Position"
@click="quickJump()"
type="primary"
>
{{ $t('firewall.quickJump') }}
</el-link>
</span>
</template>
</el-alert>
</template>
<template #toolbar> <template #toolbar>
<el-row> <el-row>
<el-col :span="16"> <el-col :span="16">
@ -111,6 +129,7 @@ import { Host } from '@/api/interface/host';
import i18n from '@/lang'; import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message'; import { MsgSuccess } from '@/utils/message';
import { ElMessageBox } from 'element-plus'; import { ElMessageBox } from 'element-plus';
import router from '@/routers';
const loading = ref(); const loading = ref();
const activeTag = ref('port'); const activeTag = ref('port');
@ -119,6 +138,7 @@ const searchName = ref();
const maskShow = ref(true); const maskShow = ref(true);
const fireStatus = ref('running'); const fireStatus = ref('running');
const fireName = ref();
const fireStatuRef = ref(); const fireStatuRef = ref();
const data = ref(); const data = ref();
@ -169,6 +189,10 @@ const onOpenDialog = async (
dialogRef.value!.acceptParams(params); dialogRef.value!.acceptParams(params);
}; };
const quickJump = () => {
router.push({ name: 'ContainerSetting' });
};
const onChangeStatus = async (row: Host.RuleInfo, status: string) => { const onChangeStatus = async (row: Host.RuleInfo, status: string) => {
let operation = let operation =
status === 'accept' status === 'accept'

View file

@ -51,13 +51,14 @@ const onPing = ref('Disable');
const acceptParams = (): void => { const acceptParams = (): void => {
loadBaseInfo(true); loadBaseInfo(true);
}; };
const emit = defineEmits(['search', 'update:status', 'update:loading', 'update:maskShow']); const emit = defineEmits(['search', 'update:status', 'update:loading', 'update:maskShow', 'update:name']);
const loadBaseInfo = async (search: boolean) => { const loadBaseInfo = async (search: boolean) => {
await loadFireBaseInfo() await loadFireBaseInfo()
.then((res) => { .then((res) => {
baseInfo.value = res.data; baseInfo.value = res.data;
onPing.value = baseInfo.value.pingStatus; onPing.value = baseInfo.value.pingStatus;
emit('update:name', baseInfo.value.name);
emit('update:status', baseInfo.value.status); emit('update:status', baseInfo.value.status);
if (search) { if (search) {
emit('search'); emit('search');