Support audit
This commit is contained in:
@@ -21,6 +21,12 @@ cache-size 512
|
||||
# prefetch-domain [yes|no]
|
||||
# prefetch-domain yes
|
||||
|
||||
# List of hosts that supply bogus NX domain results
|
||||
# bogus-nxdomain [ip]
|
||||
|
||||
# force AAAA query return SO
|
||||
# force-AAAA-SOA [yes|no]
|
||||
|
||||
# ttl for all resource record
|
||||
# rr-ttl: ttl for all record
|
||||
# rr-ttl-min: minimum ttl for resource record
|
||||
@@ -31,13 +37,22 @@ cache-size 512
|
||||
# rr-ttl-max 86400
|
||||
|
||||
# set log level
|
||||
# log-level [level], level=error, warn, info, debug
|
||||
# log-size k,m,g
|
||||
# log-level: [level], level=error, warn, info, debug
|
||||
# log-file: file path of log file.
|
||||
# log-size: size of each log file, support k,m,g
|
||||
# log-num: number of logs
|
||||
log-level error
|
||||
# log-file /var/log/smartdns.log
|
||||
# log-size 128k
|
||||
# log-num 2
|
||||
|
||||
# dns audit
|
||||
# audit-enable: enable or disable audit [yes|no]
|
||||
# audit-size size of each audit file, support k,m,g
|
||||
# audit-file /var/log/smartdns-audit.log
|
||||
# audit-size 128k
|
||||
# audit-num 2
|
||||
|
||||
# remote udp dns server list
|
||||
# server [IP]:[PORT], default port is 53
|
||||
# server 8.8.8.8
|
||||
@@ -54,6 +69,3 @@ log-level error
|
||||
# specific address to domain
|
||||
# address /domain/ip
|
||||
# address /www.example.com/1.2.3.4
|
||||
|
||||
# List of hosts that supply bogus NX domain results
|
||||
# bogus-nxdomain [ip]
|
||||
|
||||
64
src/conf.c
64
src/conf.c
@@ -24,6 +24,10 @@ int dns_conf_log_level = TLOG_ERROR;
|
||||
char dns_conf_log_file[DNS_MAX_PATH];
|
||||
int dns_conf_log_size = 1024 * 1024;
|
||||
int dns_conf_log_num = 8;
|
||||
int dns_conf_audit_enable;
|
||||
char dns_conf_audit_file[DNS_MAX_PATH];
|
||||
int dns_conf_audit_size = 1024 * 1024;
|
||||
int dns_conf_audit_num = 2;
|
||||
|
||||
art_tree dns_conf_address;
|
||||
int dns_conf_rr_ttl;
|
||||
@@ -299,6 +303,62 @@ int config_log_num(char *value)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_audit_enable(char *value)
|
||||
{
|
||||
/* read dns cache size */
|
||||
if (strncmp("yes", value, sizeof("yes")) == 0 || strncmp("YES", value, sizeof("YES")) == 0) {
|
||||
dns_conf_audit_enable = 1;
|
||||
} else if (strncmp("no", value, sizeof("no")) == 0 || strncmp("NO", value, sizeof("NO")) == 0) {
|
||||
dns_conf_audit_enable = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_audit_file(char *value)
|
||||
{
|
||||
/* read dns cache size */
|
||||
strncpy(dns_conf_audit_file, value, DNS_MAX_PATH);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_audit_size(char *value)
|
||||
{
|
||||
/* read dns cache size */
|
||||
int base = 1;
|
||||
|
||||
if (strstr(value, "k") || strstr(value, "K")) {
|
||||
base = 1024;
|
||||
} else if (strstr(value, "m") || strstr(value, "M")) {
|
||||
base = 1024 * 1024;
|
||||
} else if (strstr(value, "g") || strstr(value, "G")) {
|
||||
base = 1024 * 1024 * 1024;
|
||||
}
|
||||
|
||||
int size = atoi(value);
|
||||
if (size < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dns_conf_audit_size = size * base;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_audit_num(char *value)
|
||||
{
|
||||
/* read dns cache size */
|
||||
int num = atoi(value);
|
||||
if (num < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dns_conf_audit_num = num;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_rr_ttl(char *value)
|
||||
{
|
||||
/* read dns cache size */
|
||||
@@ -477,6 +537,10 @@ struct config_item config_item[] = {
|
||||
{"log-file", config_log_file},
|
||||
{"log-size", config_log_size},
|
||||
{"log-num", config_log_num},
|
||||
{"audit-enable", config_audit_enable},
|
||||
{"audit-file", config_audit_file},
|
||||
{"audit-size", config_audit_size},
|
||||
{"audit-num", config_audit_num},
|
||||
{"rr-ttl", config_rr_ttl},
|
||||
{"rr-ttl-min", config_rr_ttl_min},
|
||||
{"rr-ttl-max", config_rr_ttl_max},
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#define DEFAULT_DNS_PORT 53
|
||||
#define DEFAULT_DNS_TLS_PORT 853
|
||||
#define DNS_MAX_CONF_CNAME_LEN 128
|
||||
#define SMARTDNS_CONF_FILE "/etc/smartdns/smartdns.conf"
|
||||
#define SMARTDNS_LOG_FILE "/var/log/smartdns.log"
|
||||
#define SMARTDNS_AUDIT_FILE "/var/log/smartdns-audit.log"
|
||||
|
||||
struct dns_servers {
|
||||
char server[DNS_MAX_IPLEN];
|
||||
@@ -58,6 +61,11 @@ extern char dns_conf_log_file[DNS_MAX_PATH];
|
||||
extern int dns_conf_log_size;
|
||||
extern int dns_conf_log_num;
|
||||
|
||||
extern int dns_conf_audit_enable;
|
||||
extern char dns_conf_audit_file[DNS_MAX_PATH];
|
||||
extern int dns_conf_audit_size;
|
||||
extern int dns_conf_audit_num;
|
||||
|
||||
extern char dns_conf_server_name[DNS_MAX_CONF_CNAME_LEN];
|
||||
extern art_tree dns_conf_address;
|
||||
|
||||
|
||||
@@ -1079,7 +1079,7 @@ static int _dns_client_socket_recv(SSL *ssl, void *buf, int num)
|
||||
break;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
if (errno != ECONNRESET) {
|
||||
tlog(TLOG_ERROR, "SSL syscall failed, %s ", strerror(errno));
|
||||
tlog(TLOG_INFO, "SSL syscall failed, %s ", strerror(errno));
|
||||
}
|
||||
ret = -1;
|
||||
return ret;
|
||||
|
||||
@@ -133,12 +133,44 @@ struct dns_request {
|
||||
|
||||
static struct dns_server server;
|
||||
|
||||
static tlog_log *dns_audit;
|
||||
|
||||
static int _dns_server_forward_request(unsigned char *inpacket, int inpacket_len)
|
||||
{
|
||||
tlog(TLOG_ERROR, "forward request.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void _dns_server_audit_log(struct dns_request *request)
|
||||
{
|
||||
char req_host[MAX_IP_LEN];
|
||||
char req_result[MAX_IP_LEN];
|
||||
char req_time[MAX_IP_LEN];
|
||||
struct tlog_time tm;
|
||||
|
||||
if (dns_audit == NULL || !dns_conf_audit_enable) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (request->qtype == DNS_T_AAAA) {
|
||||
snprintf(req_result, sizeof(req_result), "%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x",
|
||||
request->ipv6_addr[0], request->ipv6_addr[1], request->ipv6_addr[2], request->ipv6_addr[3], request->ipv6_addr[4], request->ipv6_addr[5],
|
||||
request->ipv6_addr[6], request->ipv6_addr[7], request->ipv6_addr[8], request->ipv6_addr[9], request->ipv6_addr[10], request->ipv6_addr[11],
|
||||
request->ipv6_addr[12], request->ipv6_addr[13], request->ipv6_addr[14], request->ipv6_addr[15]);
|
||||
} else if (request->qtype == DNS_T_A) {
|
||||
snprintf(req_result, sizeof(req_result), "%d.%d.%d.%d", request->ipv4_addr[0], request->ipv4_addr[1], request->ipv4_addr[2],
|
||||
request->ipv4_addr[3]);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
gethost_by_addr(req_host, &request->addr, request->addr_len);
|
||||
tlog_localtime(&tm);
|
||||
|
||||
snprintf(req_time, sizeof(req_time), "[%.4d-%.2d-%.2d %.2d:%.2d:%.2d,%.3d]", tm.year, tm.mon, tm.mday, tm.hour, tm.min, tm.sec, tm.usec / 1000);
|
||||
|
||||
tlog_printf(dns_audit, "%s %s query %s, type %d, result %s\n", req_time, req_host, request->domain, request->qtype, req_result);
|
||||
}
|
||||
|
||||
static int _dns_recv_addr(struct dns_request *request, struct sockaddr_storage *from, socklen_t from_len)
|
||||
{
|
||||
switch (from->ss_family) {
|
||||
@@ -235,6 +267,8 @@ static int _dns_reply(struct dns_request *request)
|
||||
int ret = 0;
|
||||
int encode_len = 0;
|
||||
|
||||
_dns_server_audit_log(request);
|
||||
|
||||
memset(&head, 0, sizeof(head));
|
||||
head.id = request->id;
|
||||
head.qr = DNS_QR_ANSWER;
|
||||
@@ -797,10 +831,10 @@ errout:
|
||||
static int _dns_server_reply_SOA(int rcode, struct dns_request *request, struct dns_packet *packet)
|
||||
{
|
||||
struct dns_soa *soa;
|
||||
|
||||
|
||||
request->rcode = rcode;
|
||||
request->has_soa = 1;
|
||||
|
||||
|
||||
soa = &request->soa;
|
||||
|
||||
strcpy(soa->mname, "a.gtld-servers.net");
|
||||
@@ -1332,8 +1366,7 @@ int dns_server_socket(void)
|
||||
|
||||
fd = socket(gai->ai_family, gai->ai_socktype, gai->ai_protocol);
|
||||
if (fd < 0) {
|
||||
tlog(TLOG_ERROR, "create socket failed, family = %d, type = %d, proto = %d, %s\n",
|
||||
gai->ai_family, gai->ai_socktype, gai->ai_protocol, strerror(errno));
|
||||
tlog(TLOG_ERROR, "create socket failed, family = %d, type = %d, proto = %d, %s\n", gai->ai_family, gai->ai_socktype, gai->ai_protocol, strerror(errno));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
@@ -1362,6 +1395,25 @@ errout:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _dns_server_audit_init(void)
|
||||
{
|
||||
char *audit_file = SMARTDNS_AUDIT_FILE;
|
||||
if (dns_conf_audit_enable == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dns_conf_audit_file[0] != 0) {
|
||||
audit_file = dns_conf_audit_file;
|
||||
}
|
||||
|
||||
dns_audit = tlog_open(audit_file, dns_conf_audit_size, dns_conf_audit_num, 1, 0, 0);
|
||||
if (dns_audit == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_server_init(void)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
@@ -1377,6 +1429,11 @@ int dns_server_init(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_dns_server_audit_init() != 0) {
|
||||
tlog(TLOG_ERROR, "init audit failed.");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
memset(&server, 0, sizeof(server));
|
||||
pthread_attr_init(&attr);
|
||||
|
||||
|
||||
@@ -43,9 +43,6 @@
|
||||
#define RESOLVE_FILE "/etc/resolv.conf"
|
||||
#define MAX_LINE_LEN 1024
|
||||
#define MAX_KEY_LEN 64
|
||||
#define SMARTDNS_CONF_FILE "/etc/smartdns/smartdns.conf"
|
||||
#define SMARTDNS_LOG_PATH "/var/log"
|
||||
#define SMARTDNS_LOG_FILE "smartdns.log"
|
||||
#define SMARTDNS_PID_FILE "/var/run/smartdns.pid"
|
||||
#define TMP_BUFF_LEN_32 32
|
||||
|
||||
@@ -197,21 +194,13 @@ int smartdns_destroy_ssl(void)
|
||||
int smartdns_init(void)
|
||||
{
|
||||
int ret;
|
||||
char logdir[DNS_MAX_PATH];
|
||||
char logname[DNS_MAX_PATH];
|
||||
char *logfile = SMARTDNS_LOG_FILE;
|
||||
|
||||
if (dns_conf_log_file[0] != 0) {
|
||||
char dns_log_file[DNS_MAX_PATH];
|
||||
strncpy(dns_log_file, dns_conf_log_file, DNS_MAX_PATH);
|
||||
strncpy(logdir, dirname(dns_log_file), DNS_MAX_PATH);
|
||||
strncpy(dns_log_file, dns_conf_log_file, DNS_MAX_PATH);
|
||||
strncpy(logname, basename(dns_log_file), DNS_MAX_PATH);
|
||||
} else {
|
||||
strncpy(logdir, SMARTDNS_LOG_PATH, DNS_MAX_PATH);
|
||||
strncpy(logname, SMARTDNS_LOG_FILE, DNS_MAX_PATH);
|
||||
logfile = dns_conf_log_file;
|
||||
}
|
||||
|
||||
ret = tlog_init(logdir, logname, dns_conf_log_size, dns_conf_log_num, 1, 0, 0);
|
||||
ret = tlog_init(logfile, dns_conf_log_size, dns_conf_log_num, 1, 0, 0);
|
||||
if (ret != 0) {
|
||||
tlog(TLOG_ERROR, "start tlog failed.\n");
|
||||
goto errout;
|
||||
|
||||
763
src/tlog.c
763
src/tlog.c
File diff suppressed because it is too large
Load Diff
79
src/tlog.h
79
src/tlog.h
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* tinylog
|
||||
* Copyright (C) 2018 Ruilin Peng (Nick) <pymumu@gmail.com>
|
||||
* tinylog
|
||||
* Copyright (C) 2018 Ruilin Peng (Nick) <pymumu@gmail.com>
|
||||
* https://github.com/pymumu/tinylog
|
||||
*/
|
||||
|
||||
@@ -41,16 +41,17 @@ struct tlog_info {
|
||||
};
|
||||
|
||||
/*
|
||||
Function:Print log
|
||||
level: Current log Levels
|
||||
format: Log formats
|
||||
Function: Print log
|
||||
level: Current log Levels
|
||||
format: Log formats
|
||||
*/
|
||||
#ifndef BASE_FILE_NAME
|
||||
#define BASE_FILE_NAME __FILE__
|
||||
#endif
|
||||
#define tlog(level, format, ...) tlog_ext(level, BASE_FILE_NAME, __LINE__, __func__, 0, format, ##__VA_ARGS__)
|
||||
|
||||
extern int tlog_ext(tlog_level level, const char *file, int line, const char *func, void *userptr, const char *format, ...) __attribute__((format(printf, 6, 7)));
|
||||
extern int tlog_ext(tlog_level level, const char *file, int line, const char *func, void *userptr, const char *format, ...)
|
||||
__attribute__((format(printf, 6, 7)));
|
||||
extern int tlog_vext(tlog_level level, const char *file, int line, const char *func, void *userptr, const char *format, va_list ap);
|
||||
|
||||
/* set log level */
|
||||
@@ -59,19 +60,22 @@ extern int tlog_setlevel(tlog_level level);
|
||||
/* enalbe log to screen */
|
||||
extern void tlog_setlogscreen(int enable);
|
||||
|
||||
/*
|
||||
Function:Initialize log module
|
||||
logdir: Log Output path.
|
||||
logname: Log name.
|
||||
maxlogsize: The maximum size of a single log file.
|
||||
maxlogcount: Number of archived logs.
|
||||
block: Blocked if buffer is not sufficient.
|
||||
buffsize: Buffer size, zero for default (128K)
|
||||
multiwrite: enable multi process write mode.
|
||||
NOTICE: maxlogsize in all prcesses must be same when enable this mode.
|
||||
*/
|
||||
extern int tlog_init(const char *logdir, const char *logname, int maxlogsize, int maxlogcount, int block, int buffsize, int multiwrite);
|
||||
/* enalbe early log to screen */
|
||||
extern void tlog_set_early_printf(int enable);
|
||||
|
||||
/*
|
||||
Function: Initialize log module
|
||||
logfile: log file.
|
||||
maxlogsize: The maximum size of a single log file.
|
||||
maxlogcount: Number of archived logs.
|
||||
block: Blocked if buffer is not sufficient.
|
||||
buffsize: Buffer size, zero for default (128K)
|
||||
multiwrite: enable multi process write mode.
|
||||
NOTICE: maxlogsize in all prcesses must be same when enable this mode.
|
||||
*/
|
||||
extern int tlog_init(const char *logfile, int maxlogsize, int maxlogcount, int block, int buffsize, int multiwrite);
|
||||
|
||||
/* flush pending log message, and exit tlog */
|
||||
extern void tlog_exit(void);
|
||||
|
||||
/*
|
||||
@@ -85,6 +89,45 @@ read _tlog_format for example.
|
||||
typedef int (*tlog_format_func)(char *buff, int maxlen, struct tlog_info *info, void *userptr, const char *format, va_list ap);
|
||||
extern int tlog_reg_format_func(tlog_format_func func);
|
||||
|
||||
struct tlog_log;
|
||||
typedef struct tlog_log tlog_log;
|
||||
/*
|
||||
Function: open a new log stream, handler should close by tlog_close
|
||||
logfile: log file.
|
||||
maxlogsize: The maximum size of a single log file.
|
||||
maxlogcount: Number of archived logs.
|
||||
block: Blocked if buffer is not sufficient.
|
||||
buffsize: Buffer size, zero for default (128K)
|
||||
multiwrite: enable multi process write mode.
|
||||
NOTICE: maxlogsize in all prcesses must be same when enable this mode.
|
||||
|
||||
return: log stream handler.
|
||||
*/
|
||||
extern tlog_log *tlog_open(const char *logfile, int maxlogsize, int maxlogcount, int block, int buffsize, int multiwrite);
|
||||
|
||||
extern void tlog_close(tlog_log *log);
|
||||
|
||||
/*
|
||||
Function: Print log to log stream
|
||||
log: log stream
|
||||
format: Log formats
|
||||
*/
|
||||
extern int tlog_printf(tlog_log *log, const char *format, ...) __attribute__((format(printf, 2, 3)));
|
||||
|
||||
/*
|
||||
Function: Print log to log stream with ap
|
||||
log: log stream
|
||||
format: Log formats
|
||||
va_list: args list
|
||||
*/
|
||||
extern int tlog_vprintf(tlog_log *log, const char *format, va_list ap);
|
||||
|
||||
/* enalbe log to screen */
|
||||
extern void tlog_logscreen(tlog_log *log, int enable);
|
||||
|
||||
/* get local time */
|
||||
extern int tlog_localtime(struct tlog_time *tm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus */
|
||||
|
||||
Reference in New Issue
Block a user