Support audit

This commit is contained in:
Nick Peng
2018-11-09 23:42:01 +08:00
parent a462ed860b
commit 6e2c0da46d
8 changed files with 761 additions and 259 deletions

View File

@@ -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]

View File

@@ -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},

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

File diff suppressed because it is too large Load Diff

View File

@@ -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 {
};
/*
FunctionPrint 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);
/*
FunctionInitialize 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 */