c
This commit is contained in:
@@ -0,0 +1,246 @@
|
||||
#include "install.h"
|
||||
#include "nftables.h"
|
||||
#include "ban.h"
|
||||
#include "whitelist.h"
|
||||
#include "log.h"
|
||||
|
||||
int setup_pam_hooks(void) {
|
||||
const char *pam_file = "/etc/pam.d/sshd";
|
||||
|
||||
/* 备份原文件 */
|
||||
char backup_cmd[MAX_COMMAND_LEN];
|
||||
snprintf(backup_cmd, sizeof(backup_cmd), "cp -f %s %s.bak.blockip", pam_file, pam_file);
|
||||
system(backup_cmd);
|
||||
|
||||
/* 移除旧的钩子 */
|
||||
char remove_cmd[MAX_COMMAND_LEN];
|
||||
snprintf(remove_cmd, sizeof(remove_cmd), "sed -i '\\|%s|d' %s", INSTALL_PATH, pam_file);
|
||||
system(remove_cmd);
|
||||
|
||||
/* 添加新的钩子 */
|
||||
FILE *fp = fopen(pam_file, "r");
|
||||
if (!fp) {
|
||||
return ERROR_FILE;
|
||||
}
|
||||
|
||||
char temp_file[MAX_PATH_LEN];
|
||||
snprintf(temp_file, sizeof(temp_file), "%s.tmp", pam_file);
|
||||
FILE *temp_fp = fopen(temp_file, "w");
|
||||
if (!temp_fp) {
|
||||
fclose(fp);
|
||||
return ERROR_FILE;
|
||||
}
|
||||
|
||||
/* 在第一行插入check钩子 */
|
||||
fprintf(temp_fp, "auth optional pam_exec.so quiet %s check\n", INSTALL_PATH);
|
||||
|
||||
/* 复制原内容 */
|
||||
char line[MAX_LINE_LEN];
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
fputs(line, temp_fp);
|
||||
}
|
||||
|
||||
/* 在末尾添加clean钩子 */
|
||||
fprintf(temp_fp, "session optional pam_exec.so quiet %s clean\n", INSTALL_PATH);
|
||||
|
||||
fclose(fp);
|
||||
fclose(temp_fp);
|
||||
|
||||
rename(temp_file, pam_file);
|
||||
|
||||
log_write("[安装] PAM钩子已配置");
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int remove_pam_hooks(void) {
|
||||
const char *pam_file = "/etc/pam.d/sshd";
|
||||
|
||||
char command[MAX_COMMAND_LEN];
|
||||
snprintf(command, sizeof(command), "sed -i '\\|%s|d' %s", INSTALL_PATH, pam_file);
|
||||
system(command);
|
||||
|
||||
log_write("[卸载] PAM钩子已移除");
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int create_systemd_service(void) {
|
||||
|
||||
const char *service_file = "/etc/systemd/system/bip.service"; FILE *fp = fopen(service_file, "w");
|
||||
if (!fp) {
|
||||
return ERROR_FILE;
|
||||
}
|
||||
|
||||
fprintf(fp, "[Unit]\n");
|
||||
fprintf(fp, "Description=BIP (Block-IP) Service\n");
|
||||
fprintf(fp, "After=network.target nftables.service\n\n");
|
||||
fprintf(fp, "[Service]\n");
|
||||
fprintf(fp, "Type=oneshot\n");
|
||||
fprintf(fp, "ExecStart=%s restore\n", INSTALL_PATH);
|
||||
fprintf(fp, "RemainAfterExit=yes\n\n");
|
||||
fprintf(fp, "[Install]\n");
|
||||
fprintf(fp, "WantedBy=multi-user.target\n");
|
||||
|
||||
fclose(fp);
|
||||
|
||||
/* 重载systemd配置 */
|
||||
system("systemctl daemon-reload");
|
||||
|
||||
/* 启用服务 */
|
||||
system("systemctl enable bip.service");
|
||||
|
||||
log_write("[安装] systemd服务已创建");
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static int remove_systemd_service(void) {
|
||||
/* 停止并禁用服务 */
|
||||
system("systemctl stop bip.service 2>/dev/null");
|
||||
system("systemctl disable bip.service 2>/dev/null");
|
||||
|
||||
/* 删除服务文件 */
|
||||
remove("/etc/systemd/system/bip.service");
|
||||
|
||||
/* 重载systemd配置 */
|
||||
system("systemctl daemon-reload");
|
||||
|
||||
log_write("[卸载] systemd服务已移除");
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int install_service(void) {
|
||||
msg(C_YELLOW, "开始安装 BIP (Block-IP)...");
|
||||
|
||||
/* 复制程序到安装路径 */
|
||||
char exe_path[MAX_PATH_LEN];
|
||||
ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
|
||||
if (len != -1) {
|
||||
exe_path[len] = '\0';
|
||||
|
||||
char copy_cmd[MAX_COMMAND_LEN];
|
||||
snprintf(copy_cmd, sizeof(copy_cmd), "cp -f %s %s && chmod +x %s",
|
||||
exe_path, INSTALL_PATH, INSTALL_PATH);
|
||||
system(copy_cmd);
|
||||
}
|
||||
|
||||
/* 创建必要的目录和文件 */
|
||||
char mkdir_cmd[MAX_COMMAND_LEN];
|
||||
snprintf(mkdir_cmd, sizeof(mkdir_cmd), "mkdir -p %s && chmod 700 %s", CONFIG_DIR, CONFIG_DIR);
|
||||
system(mkdir_cmd);
|
||||
|
||||
snprintf(mkdir_cmd, sizeof(mkdir_cmd), "mkdir -p %s && chmod 770 %s", RECORD_DIR, RECORD_DIR);
|
||||
system(mkdir_cmd);
|
||||
|
||||
FILE *fp = fopen(PERSIST_FILE, "a");
|
||||
if (fp) {
|
||||
chmod(PERSIST_FILE, 0600);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
fp = fopen(WHITELIST_FILE, "a");
|
||||
if (fp) {
|
||||
chmod(WHITELIST_FILE, 0600);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/* 创建默认配置文件 */
|
||||
if (access(CONFIG_FILE, F_OK) != 0) {
|
||||
save_ban_time_to_config(DEFAULT_BAN_TIME);
|
||||
msg(C_GREEN, " ✓ 已创建默认配置文件");
|
||||
}
|
||||
|
||||
log_init();
|
||||
|
||||
/* 安装nftables */
|
||||
check_and_install_nftables();
|
||||
|
||||
/* 初始化规则 */
|
||||
init_nftables_rules();
|
||||
|
||||
/* 恢复数据 */
|
||||
restore_from_persist();
|
||||
whitelist_restore();
|
||||
|
||||
/* 配置PAM钩子 */
|
||||
setup_pam_hooks();
|
||||
|
||||
/* 创建systemd服务 */
|
||||
create_systemd_service();
|
||||
|
||||
msg(C_GREEN, "✅ 安装完成!输入 bip list 查看效果。");
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int uninstall_service(void) {
|
||||
msg(C_YELLOW, "⚠️ 开始卸载 BIP (Block-IP)...");
|
||||
|
||||
/* 移除systemd服务 */
|
||||
remove_systemd_service();
|
||||
msg(C_GREEN, " ✓ 已移除 systemd 服务");
|
||||
|
||||
/* 清除nftables规则 */
|
||||
char command[MAX_COMMAND_LEN];
|
||||
|
||||
snprintf(command, sizeof(command), "nft delete rule %s input ip saddr @%s drop 2>/dev/null",
|
||||
NFT_TABLE, NFT_SET);
|
||||
system(command);
|
||||
|
||||
snprintf(command, sizeof(command), "nft delete rule %s input ip6 saddr @%s drop 2>/dev/null",
|
||||
NFT_TABLE, NFT_SET_V6);
|
||||
system(command);
|
||||
|
||||
snprintf(command, sizeof(command), "nft delete rule %s input ip saddr @%s accept 2>/dev/null",
|
||||
NFT_TABLE, NFT_WHITELIST);
|
||||
system(command);
|
||||
|
||||
snprintf(command, sizeof(command), "nft delete rule %s input ip6 saddr @%s accept 2>/dev/null",
|
||||
NFT_TABLE, NFT_WHITELIST_V6);
|
||||
system(command);
|
||||
|
||||
snprintf(command, sizeof(command), "nft delete set %s %s 2>/dev/null", NFT_TABLE, NFT_SET);
|
||||
system(command);
|
||||
|
||||
snprintf(command, sizeof(command), "nft delete set %s %s 2>/dev/null", NFT_TABLE, NFT_SET_V6);
|
||||
system(command);
|
||||
|
||||
snprintf(command, sizeof(command), "nft delete set %s %s 2>/dev/null", NFT_TABLE, NFT_WHITELIST);
|
||||
system(command);
|
||||
|
||||
snprintf(command, sizeof(command), "nft delete set %s %s 2>/dev/null", NFT_TABLE, NFT_WHITELIST_V6);
|
||||
system(command);
|
||||
|
||||
msg(C_GREEN, " ✓ 已清除防火墙规则");
|
||||
|
||||
/* 移除PAM钩子 */
|
||||
remove_pam_hooks();
|
||||
msg(C_GREEN, " ✓ 已移除 PAM 钩子");
|
||||
|
||||
/* 询问是否删除数据文件 */
|
||||
printf("是否删除配置目录和日志? [y/N] ");
|
||||
char answer[10];
|
||||
if (fgets(answer, sizeof(answer), stdin)) {
|
||||
if (answer[0] == 'y' || answer[0] == 'Y') {
|
||||
char rm_cmd[MAX_COMMAND_LEN];
|
||||
snprintf(rm_cmd, sizeof(rm_cmd), "rm -rf %s", CONFIG_DIR);
|
||||
system(rm_cmd);
|
||||
|
||||
remove(LOG_FILE);
|
||||
char log_backup[MAX_PATH_LEN];
|
||||
snprintf(log_backup, sizeof(log_backup), "%s.1", LOG_FILE);
|
||||
remove(log_backup);
|
||||
|
||||
msg(C_GREEN, " ✓ 已删除数据文件");
|
||||
} else {
|
||||
printf("%s ↳ 保留: %s, %s%s\n",
|
||||
C_CYAN, CONFIG_DIR, LOG_FILE, C_RESET);
|
||||
}
|
||||
}
|
||||
|
||||
/* 删除程序文件 */
|
||||
remove(INSTALL_PATH);
|
||||
msg(C_GREEN, " ✓ 已删除程序文件");
|
||||
|
||||
msg(C_GREEN, "\n✅ 卸载完成!");
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user