tls: support certificate verify.
This commit is contained in:
@@ -107,6 +107,7 @@ struct dns_server_info {
|
||||
SSL *ssl;
|
||||
SSL_CTX *ssl_ctx;
|
||||
SSL_SESSION *ssl_session;
|
||||
char skip_check_cert;
|
||||
dns_server_status status;
|
||||
|
||||
struct dns_server_buff send_buff;
|
||||
@@ -714,6 +715,39 @@ static char *_dns_client_server_get_spki(struct dns_server_info *server_info, in
|
||||
return spki;
|
||||
}
|
||||
|
||||
static int _dns_client_set_trusted_cert(SSL_CTX *ssl_ctx)
|
||||
{
|
||||
char *cafile = NULL;
|
||||
char *capath = NULL;
|
||||
int cert_path_set = 0;
|
||||
|
||||
if (dns_conf_ca_file[0]) {
|
||||
cafile = dns_conf_ca_file;
|
||||
}
|
||||
|
||||
if (dns_conf_ca_path[0]) {
|
||||
capath = dns_conf_ca_path;
|
||||
}
|
||||
|
||||
if (cafile == NULL && capath == NULL) {
|
||||
if (SSL_CTX_set_default_verify_paths(ssl_ctx)) {
|
||||
cafile = "/etc/ssl/certs/ca-certificates.crt";
|
||||
capath = "/etc/ssl/certs";
|
||||
} else {
|
||||
cert_path_set = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (cert_path_set == 0) {
|
||||
if (!SSL_CTX_load_verify_locations(ssl_ctx, cafile, capath)) {
|
||||
tlog(TLOG_WARN, "load certificate from %s:%s failed.", cafile, capath);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* add dns server information */
|
||||
static int _dns_client_server_add(char *server_ip, char *server_host, int port, dns_server_type_t server_type,
|
||||
struct client_dns_server_flags *flags)
|
||||
@@ -724,6 +758,7 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
|
||||
int ttl = 0;
|
||||
char port_s[8];
|
||||
int sock_type;
|
||||
char skip_check_cert = 0;
|
||||
|
||||
switch (server_type) {
|
||||
case DNS_SERVER_UDP: {
|
||||
@@ -748,11 +783,13 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
|
||||
}
|
||||
}
|
||||
sock_type = SOCK_STREAM;
|
||||
skip_check_cert = flag_https->skip_check_cert;
|
||||
} break;
|
||||
case DNS_SERVER_TLS: {
|
||||
struct client_dns_server_flag_tls *flag_tls = &flags->tls;
|
||||
spki_data_len = flag_tls->spi_len;
|
||||
sock_type = SOCK_STREAM;
|
||||
skip_check_cert = flag_tls->skip_check_cert;
|
||||
} break;
|
||||
case DNS_SERVER_TCP:
|
||||
sock_type = SOCK_STREAM;
|
||||
@@ -798,6 +835,7 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
|
||||
server_info->status = DNS_SERVER_STATUS_INIT;
|
||||
server_info->ttl = ttl;
|
||||
server_info->ttl_range = 0;
|
||||
server_info->skip_check_cert = skip_check_cert;
|
||||
memcpy(&server_info->flags, flags, sizeof(server_info->flags));
|
||||
|
||||
/* exclude this server from default group */
|
||||
@@ -815,6 +853,11 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port,
|
||||
#else
|
||||
server_info->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
#endif
|
||||
if (_dns_client_set_trusted_cert(server_info->ssl_ctx) != 0) {
|
||||
tlog(TLOG_WARN, "disable check certificate for %s.", server_info->ip);
|
||||
server_info->skip_check_cert = 1;
|
||||
}
|
||||
|
||||
if (server_info->ssl_ctx == NULL) {
|
||||
tlog(TLOG_ERROR, "init ssl failed.");
|
||||
goto errout;
|
||||
@@ -2078,6 +2121,14 @@ static int _dns_client_tls_verify(struct dns_server_info *server_info)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (server_info->skip_check_cert == 0) {
|
||||
long res = SSL_get_verify_result(server_info->ssl);
|
||||
if (res != X509_V_OK) {
|
||||
tlog(TLOG_WARN, "peer server certificate verify failed.");
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
cert_name = X509_get_subject_name(cert);
|
||||
if (cert_name == NULL) {
|
||||
tlog(TLOG_ERROR, "get subject name failed.");
|
||||
@@ -2094,7 +2145,7 @@ static int _dns_client_tls_verify(struct dns_server_info *server_info)
|
||||
/* check tls host */
|
||||
tls_host_verify = _dns_client_server_get_tls_host_verify(server_info);
|
||||
if (tls_host_verify) {
|
||||
if (_dns_client_tls_matchName(peer_CN, tls_host_verify, strnlen(tls_host_verify, DNS_MAX_CNAME_LEN)) != 0) {
|
||||
if (_dns_client_tls_matchName(tls_host_verify, peer_CN, strnlen(peer_CN, DNS_MAX_CNAME_LEN)) != 0) {
|
||||
tlog(TLOG_INFO, "server %s CN is invalid, peer CN: %s, expect CN: %s", server_info->ip, peer_CN,
|
||||
tls_host_verify);
|
||||
goto errout;
|
||||
|
||||
@@ -70,6 +70,7 @@ struct client_dns_server_flag_tls {
|
||||
int spi_len;
|
||||
char hostname[DNS_MAX_CNAME_LEN];
|
||||
char tls_host_verify[DNS_MAX_CNAME_LEN];
|
||||
char skip_check_cert;
|
||||
};
|
||||
|
||||
struct client_dns_server_flag_https {
|
||||
@@ -79,6 +80,7 @@ struct client_dns_server_flag_https {
|
||||
char httphost[DNS_MAX_CNAME_LEN];
|
||||
char path[DNS_MAX_CNAME_LEN];
|
||||
char tls_host_verify[DNS_MAX_CNAME_LEN];
|
||||
char skip_check_cert;
|
||||
};
|
||||
|
||||
struct client_dns_server_flags {
|
||||
|
||||
@@ -68,6 +68,10 @@ char dns_conf_log_file[DNS_MAX_PATH];
|
||||
size_t dns_conf_log_size = 1024 * 1024;
|
||||
int dns_conf_log_num = 8;
|
||||
|
||||
/* CA file */
|
||||
char dns_conf_ca_file[DNS_MAX_PATH];
|
||||
char dns_conf_ca_path[DNS_MAX_PATH];
|
||||
|
||||
/* auditing */
|
||||
int dns_conf_audit_enable = 0;
|
||||
int dns_conf_audit_log_SOA;
|
||||
@@ -246,6 +250,7 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
|
||||
{"spki-pin", required_argument, NULL, 'p'}, /* check SPKI pin */
|
||||
{"host-name", required_argument, NULL, 'h'}, /* host name */
|
||||
{"http-host", required_argument, NULL, 'H'}, /* http host */
|
||||
{"no-check-certificate", no_argument, NULL, 'N'}, /* do not check certificate */
|
||||
{"tls-host-verify", required_argument, NULL, 'V' }, /* verify tls hostname */
|
||||
{"group", required_argument, NULL, 'g'}, /* add to group */
|
||||
{"exclude-default-group", no_argument, NULL, 'E'}, /* ecluse this from default group */
|
||||
@@ -340,6 +345,10 @@ static int _config_server(int argc, char *argv[], dns_server_type_t type, int de
|
||||
safe_strncpy(server->tls_host_verify, optarg, DNS_MAX_CNAME_LEN);
|
||||
break;
|
||||
}
|
||||
case 'N': {
|
||||
server->skip_check_cert = 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1370,6 +1379,8 @@ static struct config_item _config_item[] = {
|
||||
CONF_CUSTOM("ignore-ip", _conf_ip_ignore, NULL),
|
||||
CONF_CUSTOM("edns-client-subnet", _conf_edns_client_subnet, NULL),
|
||||
CONF_CUSTOM("domain-rules", _conf_domain_rules, NULL),
|
||||
CONF_STRING("ca-file", (char *)&dns_conf_ca_file, DNS_MAX_PATH),
|
||||
CONF_STRING("ca-path", (char *)&dns_conf_ca_path, DNS_MAX_PATH),
|
||||
CONF_CUSTOM("conf-file", config_addtional_file, NULL),
|
||||
CONF_END(),
|
||||
};
|
||||
|
||||
@@ -145,6 +145,7 @@ struct dns_servers {
|
||||
unsigned int server_flag;
|
||||
int ttl;
|
||||
dns_server_type_t type;
|
||||
char skip_check_cert;
|
||||
char spki[DNS_MAX_SPKI_LEN];
|
||||
char hostname[DNS_MAX_CNAME_LEN];
|
||||
char httphost[DNS_MAX_CNAME_LEN];
|
||||
@@ -211,6 +212,9 @@ extern char dns_conf_log_file[DNS_MAX_PATH];
|
||||
extern size_t dns_conf_log_size;
|
||||
extern int dns_conf_log_num;
|
||||
|
||||
extern char dns_conf_ca_file[DNS_MAX_PATH];
|
||||
extern char dns_conf_ca_path[DNS_MAX_PATH];
|
||||
|
||||
extern struct dns_domain_check_order dns_conf_check_order;
|
||||
|
||||
extern struct dns_server_groups dns_conf_server_groups[DNS_NAX_GROUP_NUMBER];
|
||||
|
||||
@@ -1026,7 +1026,7 @@ struct ping_host_struct *fast_ping_start(PING_TYPE type, const char *host, int c
|
||||
uint32_t addrkey;
|
||||
char ip_str[PING_MAX_HOSTLEN];
|
||||
int port = -1;
|
||||
FAST_PING_TYPE ping_type;
|
||||
FAST_PING_TYPE ping_type = FAST_PING_END;
|
||||
unsigned int seed;
|
||||
int ret = 0;
|
||||
|
||||
|
||||
@@ -160,6 +160,7 @@ static int _smartdns_add_servers(void)
|
||||
safe_strncpy(flag_http->httphost, dns_conf_servers[i].httphost, sizeof(flag_http->httphost));
|
||||
safe_strncpy(flag_http->tls_host_verify, dns_conf_servers[i].tls_host_verify,
|
||||
sizeof(flag_http->tls_host_verify));
|
||||
flag_http->skip_check_cert = dns_conf_servers[i].skip_check_cert;
|
||||
} break;
|
||||
case DNS_SERVER_TLS: {
|
||||
struct client_dns_server_flag_tls *flag_tls = &flags.tls;
|
||||
@@ -167,6 +168,8 @@ static int _smartdns_add_servers(void)
|
||||
safe_strncpy(flag_tls->hostname, dns_conf_servers[i].hostname, sizeof(flag_tls->hostname));
|
||||
safe_strncpy(flag_tls->tls_host_verify, dns_conf_servers[i].tls_host_verify,
|
||||
sizeof(flag_tls->tls_host_verify));
|
||||
flag_tls->skip_check_cert = dns_conf_servers[i].skip_check_cert;
|
||||
|
||||
} break;
|
||||
case DNS_SERVER_TCP:
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user