Files
sunhpc-go/internal/system/selinux.go
2026-02-14 05:36:00 +08:00

98 lines
2.6 KiB
Go

package system
import (
"fmt"
"os"
"os/exec"
"strings"
)
// ConfigureSELinux 设置 SELinux 模式
// 参数: mode - enforcing, permissive, disabled
// 返回: error - 配置错误
func ConfigureSELinux(mode string) error {
if mode == "" {
return nil
}
// 验证输入
mode = strings.ToLower(strings.TrimSpace(mode))
validModes := map[string]bool{
"enforcing": true,
"permissive": true,
"disabled": true,
}
if !validModes[mode] {
return fmt.Errorf("无效的 SELinux 模式: %s (可选: enforcing, permissive, disabled)", mode)
}
// 检查 SELinux 是否可用
if _, err := os.Stat("/selinux/enforce"); os.IsNotExist(err) {
if _, err := os.Stat("/sys/fs/selinux/enforce"); os.IsNotExist(err) {
return fmt.Errorf("系统不支持 SELinux 或未启用")
}
}
// 临时生效
if mode != "disabled" { // disabled 需要重启才能完全生效
cmd := exec.Command("setenforce", mode)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return fmt.Errorf("setenforce %s 失败: %v", mode, err)
}
}
// 持久化配置
return persistSELinuxMode(mode)
}
// persistSELinuxMode 修改 /etc/selinux/config 实现持久化
func persistSELinuxMode(mode string) error {
const selinuxConfig = "/etc/selinux/config"
// 读取配置文件
content, err := os.ReadFile(selinuxConfig)
if err != nil {
// 如果文件不存在,创建默认配置
if os.IsNotExist(err) {
defaultConfig := fmt.Sprintf(`# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=%s
# SELINUXTYPE= can take one of three two values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
`, mode)
return os.WriteFile(selinuxConfig, []byte(defaultConfig), 0644)
}
return err
}
// 替换 SELINUX= 行
lines := strings.Split(string(content), "\n")
for i, line := range lines {
if strings.HasPrefix(line, "SELINUX=") {
lines[i] = fmt.Sprintf("SELINUX=%s", mode)
break
}
}
return os.WriteFile(selinuxConfig, []byte(strings.Join(lines, "\n")), 0644)
}
// GetSELinuxMode 获取当前 SELinux 模式
func GetSELinuxMode() (string, error) {
cmd := exec.Command("getenforce")
output, err := cmd.Output()
if err != nil {
return "", err
}
return strings.ToLower(strings.TrimSpace(string(output))), nil
}