Support TLS SPKI verify
This commit is contained in:
@@ -446,9 +446,9 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
|
|||||||
|audit-size|audit log size|128K|number+K,M,G|audit-size 128K
|
|audit-size|audit log size|128K|number+K,M,G|audit-size 128K
|
||||||
|audit-num|archived audit log number|2|Integer|audit-num 2
|
|audit-num|archived audit log number|2|Integer|audit-num 2
|
||||||
|conf-file|additional conf file|None|File path|conf-file /etc/smartdns/smartdns.more.conf
|
|conf-file|additional conf file|None|File path|conf-file /etc/smartdns/smartdns.more.conf
|
||||||
|server|Upstream UDP DNS server|None|Repeatable <br>[ip][:port]: Server IP, port optional. <br>[-blacklist-ip]: The `-blacklist-ip` parameter is to filtering IPs which is configured by `blacklist-ip`. <br>[-check-edns]: edns filter. <br>[-group [group] ...]: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>[-exclude-default-group]: Exclude DNS servers from the default group| server 8.8.8.8:53 -blacklist-ip -check-edns
|
|server|Upstream UDP DNS server|None|Repeatable <br>`[ip][:port]`: Server IP, port optional. <br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-check-edns]`: edns filter. <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server 8.8.8.8:53 -blacklist-ip -check-edns
|
||||||
|server-tcp|Upstream TCP DNS server|None|Repeatable <br>[ip][:port]: Server IP, port optional. <br>[-blacklist-ip]: The `-blacklist-ip` parameter is to filtering IPs which is configured by `blacklist-ip`. <br>[-group [group] ...]: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>[-exclude-default-group]: Exclude DNS servers from the default group| server-tcp 8.8.8.8:53
|
|server-tcp|Upstream TCP DNS server|None|Repeatable <br>`[ip][:port]`: Server IP, port optional. <br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server-tcp 8.8.8.8:53
|
||||||
|server-tls|Upstream TLS DNS server|None|Repeatable <br>[ip][:port]: Server IP, port optional. <br>[-blacklist-ip]: The `-blacklist-ip` parameter is to filtering IPs which is configured by `blacklist-ip`. <br>[-group [group] ...]: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>[-exclude-default-group]: Exclude DNS servers from the default group| server-tls 8.8.8.8:853
|
|server-tls|Upstream TLS DNS server|None|Repeatable <br>`[ip][:port]`: Server IP, port optional. <br>`[-spki-pin [sha256-pin]]`: TLS verify SPKI value, a base64 encoded SHA256 hash<br>`[-blacklist-ip]`: The "-blacklist-ip" parameter is to filtering IPs which is configured by "blacklist-ip". <br>`[-group [group] ...]`: The group to which the DNS server belongs, such as office, foreign, use with nameserver. <br>`[-exclude-default-group]`: Exclude DNS servers from the default group| server-tls 8.8.8.8:853
|
||||||
|address|Domain IP address|None|address /domain/[ip\|-\|-4\|-6\|#\|#4\|#6], `-` for ignore, `#` for return SOA, `4` for IPV4, `6` for IPV6| address /www.example.com/1.2.3.4
|
|address|Domain IP address|None|address /domain/[ip\|-\|-4\|-6\|#\|#4\|#6], `-` for ignore, `#` for return SOA, `4` for IPV4, `6` for IPV6| address /www.example.com/1.2.3.4
|
||||||
|nameserver|To query domain with specific server group|None|nameserver /domain/[group\|-], `group` is the group name, `-` means ignore this rule, use the `-group` parameter in the related server|nameserver /www.example.com/office
|
|nameserver|To query domain with specific server group|None|nameserver /domain/[group\|-], `group` is the group name, `-` means ignore this rule, use the `-group` parameter in the related server|nameserver /www.example.com/office
|
||||||
|ipset|Domain IPSet|None|ipset /domain/[ipset\|-], `-` for ignore|ipset /www.example.com/pass
|
|ipset|Domain IPSet|None|ipset /domain/[ipset\|-], `-` for ignore|ipset /www.example.com/pass
|
||||||
|
|||||||
@@ -447,9 +447,9 @@ rtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms
|
|||||||
|audit-size|审计大小|128K|数字+K,M,G|audit-size 128K
|
|audit-size|审计大小|128K|数字+K,M,G|audit-size 128K
|
||||||
|audit-num|审计归档个数|2|数字|audit-num 2
|
|audit-num|审计归档个数|2|数字|audit-num 2
|
||||||
|conf-file|附加配置文件|无|文件路径|conf-file /etc/smartdns/smartdns.more.conf
|
|conf-file|附加配置文件|无|文件路径|conf-file /etc/smartdns/smartdns.more.conf
|
||||||
|server|上游UDP DNS|无|可重复<br>[ip][:port]:服务器IP,端口可选。<br>[-blacklist-ip]:blacklist-ip参数指定使用blacklist-ip配置IP过滤结果。<br>[-check-edns]:edns过滤。<br>[-group [group] ...]:DNS服务器所属组,比如office, foreign,和nameserver配套使用。<br>[-exclude-default-group]:将DNS服务器从默认组中排除| server 8.8.8.8:53 -blacklist-ip -check-edns -group g1
|
|server|上游UDP DNS|无|可重复<br>`[ip][:port]`:服务器IP,端口可选。<br>`[-blacklist-ip]`:blacklist-ip参数指定使用blacklist-ip配置IP过滤结果。<br>`[-check-edns]`:edns过滤。<br>`[-group [group] ...]`:DNS服务器所属组,比如office, foreign,和nameserver配套使用。<br>`[-exclude-default-group]`:将DNS服务器从默认组中排除| server 8.8.8.8:53 -blacklist-ip -check-edns -group g1
|
||||||
|server-tcp|上游TCP DNS|无|可重复<br>[ip][:port]:服务器IP,端口可选。<br>[-blacklist-ip]:blacklist-ip参数指定使用blacklist-ip配置IP过滤结果。<br>[-group [group] ...]:DNS服务器所属组,比如office, foreign,和nameserver配套使用。<br>[-exclude-default-group]:将DNS服务器从默认组中排除| server-tcp 8.8.8.8:53
|
|server-tcp|上游TCP DNS|无|可重复<br>`[ip][:port]`:服务器IP,端口可选。<br>`[-blacklist-ip]`:blacklist-ip参数指定使用blacklist-ip配置IP过滤结果。<br>`[-group [group] ...]`:DNS服务器所属组,比如office, foreign,和nameserver配套使用。<br>`[-exclude-default-group]`:将DNS服务器从默认组中排除| server-tcp 8.8.8.8:53
|
||||||
|server-tls|上游TLS DNS|无|可重复<br>[ip][:port]:服务器IP,端口可选。<br>[-blacklist-ip]:blacklist-ip参数指定使用blacklist-ip配置IP过滤结果。<br>[-group [group] ...]:DNS服务器所属组,比如office, foreign,和nameserver配套使用。<br>[-exclude-default-group]:将DNS服务器从默认组中排除| server-tls 8.8.8.8:853
|
|server-tls|上游TLS DNS|无|可重复<br>`[ip][:port]`:服务器IP,端口可选。<br>`[-spki-pin [sha256-pin]]`: TLS合法性校验SPKI值,base64编码的sha256 SPKI pin值<br>`[-blacklist-ip]`:blacklist-ip参数指定使用blacklist-ip配置IP过滤结果。<br>`[-group [group] ...]`:DNS服务器所属组,比如office, foreign,和nameserver配套使用。<br>`[-exclude-default-group]`:将DNS服务器从默认组中排除| server-tls 8.8.8.8:853
|
||||||
|address|指定域名IP地址|无|address /domain/[ip\|-\|-4\|-6\|#\|#4\|#6] <br>`-`表示忽略 <br>`#`表示返回SOA <br>`4`表示IPV4 <br>`6`表示IPV6| address /www.example.com/1.2.3.4
|
|address|指定域名IP地址|无|address /domain/[ip\|-\|-4\|-6\|#\|#4\|#6] <br>`-`表示忽略 <br>`#`表示返回SOA <br>`4`表示IPV4 <br>`6`表示IPV6| address /www.example.com/1.2.3.4
|
||||||
|nameserver|指定域名使用server组解析|无|nameserver /domain/[group\|-], `group`为组名,`-`表示忽略此规则,配套server中的`-group`参数使用| nameserver /www.example.com/office
|
|nameserver|指定域名使用server组解析|无|nameserver /domain/[group\|-], `group`为组名,`-`表示忽略此规则,配套server中的`-group`参数使用| nameserver /www.example.com/office
|
||||||
|ipset|域名IPSET|None|ipset /domain/[ipset\|-], `-`表示忽略|ipset /www.example.com/pass
|
|ipset|域名IPSET|None|ipset /domain/[ipset\|-], `-`表示忽略|ipset /www.example.com/pass
|
||||||
|
|||||||
@@ -93,7 +93,10 @@ log-level info
|
|||||||
# server-tcp 8.8.8.8
|
# server-tcp 8.8.8.8
|
||||||
|
|
||||||
# remote tls dns server list
|
# remote tls dns server list
|
||||||
# server-tls [IP]:[PORT] [-blacklist-ip] [-group [group] ...] [-exclude-default-group]
|
# server-tls [IP]:[PORT] [-blacklist-ip] [-spki-pin [sha256-pin]] [-group [group] ...] [-exclude-default-group]
|
||||||
|
# -spki-pin: TLS spki pin to verify.
|
||||||
|
# Get SKPI with this command:
|
||||||
|
# echo | openssl s_client -connect '[ip]:853' | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
|
||||||
# default port is 853
|
# default port is 853
|
||||||
# server-tls 8.8.8.8
|
# server-tls 8.8.8.8
|
||||||
# server-tls 1.0.0.1
|
# server-tls 1.0.0.1
|
||||||
@@ -115,4 +118,4 @@ log-level info
|
|||||||
# specific ipset to domain
|
# specific ipset to domain
|
||||||
# ipset /domain/[ipset|-]
|
# ipset /domain/[ipset|-]
|
||||||
# ipset /www.example.com/block, set ipset with ipset name of block
|
# ipset /www.example.com/block, set ipset with ipset name of block
|
||||||
# ipset /www.example.com/-, ignore this domain
|
# ipset /www.example.com/-, ignore this domain
|
||||||
|
|||||||
102
src/dns_client.c
102
src/dns_client.c
@@ -93,6 +93,9 @@ struct dns_server_info {
|
|||||||
/* server type */
|
/* server type */
|
||||||
dns_server_type_t type;
|
dns_server_type_t type;
|
||||||
|
|
||||||
|
unsigned char *spki;
|
||||||
|
int spki_len;
|
||||||
|
|
||||||
/* client socket */
|
/* client socket */
|
||||||
int fd;
|
int fd;
|
||||||
int ttl;
|
int ttl;
|
||||||
@@ -535,9 +538,25 @@ void _dns_client_group_remove_all(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* add dns server information */
|
/* add dns server information */
|
||||||
int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_type_t server_type, unsigned int server_flag, unsigned int result_flag, int ttl)
|
int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_type_t server_type, unsigned int server_flag, unsigned int result_flag, int ttl, char *spki)
|
||||||
{
|
{
|
||||||
struct dns_server_info *server_info = NULL;
|
struct dns_server_info *server_info = NULL;
|
||||||
|
unsigned char *spki_data = NULL;
|
||||||
|
int spki_data_len = 0;
|
||||||
|
|
||||||
|
/* read SPKI */
|
||||||
|
if (spki && (strlen(spki) < DNS_MAX_SPKI_LEN)) {
|
||||||
|
spki_data = malloc(DNS_MAX_SPKI_LEN);
|
||||||
|
if (spki_data) {
|
||||||
|
memset(spki_data, 0, DNS_MAX_SPKI_LEN);
|
||||||
|
spki_data_len = SSL_base64_decode(spki, spki_data);
|
||||||
|
if (spki_data_len != SHA256_DIGEST_LENGTH) {
|
||||||
|
free(spki_data);
|
||||||
|
spki_data = NULL;
|
||||||
|
spki_data_len = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_dns_client_server_exist(gai, server_type) == 0) {
|
if (_dns_client_server_exist(gai, server_type) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -562,6 +581,8 @@ int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_typ
|
|||||||
server_info->result_flag = result_flag;
|
server_info->result_flag = result_flag;
|
||||||
server_info->ttl = ttl;
|
server_info->ttl = ttl;
|
||||||
server_info->ttl_range = 0;
|
server_info->ttl_range = 0;
|
||||||
|
server_info->spki = spki_data;
|
||||||
|
server_info->spki_len = spki_data_len;
|
||||||
|
|
||||||
if ((server_flag & SERVER_FLAG_EXCLUDE_DEFAULT) == 0) {
|
if ((server_flag & SERVER_FLAG_EXCLUDE_DEFAULT) == 0) {
|
||||||
if (_dns_client_add_to_group(DNS_SERVER_GROUP_DEFAULT, server_info) != 0) {
|
if (_dns_client_add_to_group(DNS_SERVER_GROUP_DEFAULT, server_info) != 0) {
|
||||||
@@ -605,6 +626,10 @@ int _dns_client_server_add(char *server_ip, struct addrinfo *gai, dns_server_typ
|
|||||||
atomic_inc(&client.dns_server_num);
|
atomic_inc(&client.dns_server_num);
|
||||||
return 0;
|
return 0;
|
||||||
errout:
|
errout:
|
||||||
|
if (spki_data) {
|
||||||
|
free(spki_data);
|
||||||
|
}
|
||||||
|
|
||||||
if (server_info) {
|
if (server_info) {
|
||||||
if (server_info->ssl_ctx) {
|
if (server_info->ssl_ctx) {
|
||||||
SSL_CTX_free(server_info->ssl_ctx);
|
SSL_CTX_free(server_info->ssl_ctx);
|
||||||
@@ -673,6 +698,10 @@ void _dns_client_server_remove_all(void)
|
|||||||
{
|
{
|
||||||
list_del(&server_info->list);
|
list_del(&server_info->list);
|
||||||
_dns_client_server_close(server_info);
|
_dns_client_server_close(server_info);
|
||||||
|
if (server_info->spki) {
|
||||||
|
free(server_info->spki);
|
||||||
|
server_info->spki = NULL;
|
||||||
|
}
|
||||||
free(server_info);
|
free(server_info);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&client.server_list_lock);
|
pthread_mutex_unlock(&client.server_list_lock);
|
||||||
@@ -707,7 +736,7 @@ int _dns_client_server_remove(char *server_ip, struct addrinfo *gai, dns_server_
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _dns_client_server_operate(char *server_ip, int port, dns_server_type_t server_type, unsigned int server_flag, unsigned int result_flag, int ttl, int operate)
|
int _dns_client_server_operate(char *server_ip, int port, dns_server_type_t server_type, unsigned int server_flag, unsigned int result_flag, int ttl, char *spki, int operate)
|
||||||
{
|
{
|
||||||
char port_s[8];
|
char port_s[8];
|
||||||
int sock_type;
|
int sock_type;
|
||||||
@@ -741,7 +770,7 @@ int _dns_client_server_operate(char *server_ip, int port, dns_server_type_t serv
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (operate == 0) {
|
if (operate == 0) {
|
||||||
ret = _dns_client_server_add(server_ip, gai, server_type, server_flag, result_flag, ttl);
|
ret = _dns_client_server_add(server_ip, gai, server_type, server_flag, result_flag, ttl, spki);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
@@ -760,14 +789,14 @@ errout:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_client_add_server(char *server_ip, int port, dns_server_type_t server_type, unsigned server_flag, unsigned int result_flag, int ttl)
|
int dns_client_add_server(char *server_ip, int port, dns_server_type_t server_type, unsigned server_flag, unsigned int result_flag, int ttl, char *spki)
|
||||||
{
|
{
|
||||||
return _dns_client_server_operate(server_ip, port, server_type, server_flag, result_flag, ttl, 0);
|
return _dns_client_server_operate(server_ip, port, server_type, server_flag, result_flag, ttl, spki, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_client_remove_server(char *server_ip, int port, dns_server_type_t server_type)
|
int dns_client_remove_server(char *server_ip, int port, dns_server_type_t server_type)
|
||||||
{
|
{
|
||||||
return _dns_client_server_operate(server_ip, port, server_type, 0, 0, 0, 1);
|
return _dns_client_server_operate(server_ip, port, server_type, 0, 0, 0, NULL, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dns_server_num(void)
|
int dns_server_num(void)
|
||||||
@@ -1653,11 +1682,12 @@ static int _dns_client_tls_verify(struct dns_server_info *server_info)
|
|||||||
{
|
{
|
||||||
X509 *cert = NULL;
|
X509 *cert = NULL;
|
||||||
char peer_CN[256];
|
char peer_CN[256];
|
||||||
const EVP_MD *digest;
|
|
||||||
unsigned char md[EVP_MAX_MD_SIZE];
|
|
||||||
unsigned int n;
|
|
||||||
char cert_fingerprint[256];
|
char cert_fingerprint[256];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
int key_len = 0;
|
||||||
|
unsigned char *key_data = NULL;
|
||||||
|
unsigned char *key_data_tmp = NULL;
|
||||||
|
unsigned char *key_sha256 = NULL;
|
||||||
|
|
||||||
cert = SSL_get_peer_certificate(server_info->ssl);
|
cert = SSL_get_peer_certificate(server_info->ssl);
|
||||||
if (cert == NULL) {
|
if (cert == NULL) {
|
||||||
@@ -1666,28 +1696,66 @@ static int _dns_client_tls_verify(struct dns_server_info *server_info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, peer_CN, 256);
|
X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, peer_CN, 256);
|
||||||
|
|
||||||
tlog(TLOG_DEBUG, "peer CN: %s", peer_CN);
|
tlog(TLOG_DEBUG, "peer CN: %s", peer_CN);
|
||||||
|
|
||||||
digest = EVP_get_digestbyname("sha256");
|
/* get spki pin */
|
||||||
X509_digest(cert, digest, md, &n);
|
key_len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), NULL);
|
||||||
|
if (key_len <= 0 ) {
|
||||||
|
tlog(TLOG_ERROR, "get x509 public key failed.");
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
key_data = OPENSSL_malloc(key_len);
|
||||||
|
key_data_tmp = key_data;
|
||||||
|
if (key_data == NULL) {
|
||||||
|
tlog(TLOG_ERROR, "malloc memory failed.");
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &key_data_tmp);
|
||||||
|
|
||||||
|
key_sha256 = SSL_SHA256(key_data, key_len, 0);
|
||||||
|
if (key_sha256 == NULL) {
|
||||||
|
tlog(TLOG_ERROR, "get sha256 failed.");
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
char *ptr = cert_fingerprint;
|
char *ptr = cert_fingerprint;
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
|
||||||
*ptr = _dns_client_to_hex(md[i] >> 4 & 0xF);
|
*ptr = _dns_client_to_hex(key_sha256[i] >> 4 & 0xF);
|
||||||
ptr++;
|
ptr++;
|
||||||
*ptr = _dns_client_to_hex(md[i] & 0xF);
|
*ptr = _dns_client_to_hex(key_sha256[i] & 0xF);
|
||||||
ptr++;
|
ptr++;
|
||||||
*ptr = ':';
|
*ptr = ':';
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
ptr--;
|
ptr--;
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
tlog(TLOG_DEBUG, "cert fingerprint(%s): %s", "sha256", cert_fingerprint);
|
tlog(TLOG_DEBUG, "cert SPKI pin(%s): %s", "sha256", cert_fingerprint);
|
||||||
|
|
||||||
|
if (server_info->spki) {
|
||||||
|
if (memcmp(server_info->spki, key_sha256, server_info->spki_len) != 0) {
|
||||||
|
tlog(TLOG_INFO, "server %s cert spki is invalid", server_info->ip);
|
||||||
|
goto errout;
|
||||||
|
} else {
|
||||||
|
tlog(TLOG_DEBUG, "server %s cert spki verify succeed", server_info->ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OPENSSL_free(key_data);
|
||||||
X509_free(cert);
|
X509_free(cert);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
errout:
|
||||||
|
if (key_data) {
|
||||||
|
OPENSSL_free(key_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cert) {
|
||||||
|
X509_free(cert);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _dns_client_process_tls(struct dns_server_info *server_info, struct epoll_event *event, unsigned long now)
|
static int _dns_client_process_tls(struct dns_server_info *server_info, struct epoll_event *event, unsigned long now)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ int dns_client_query(char *domain, int qtype, dns_client_callback callback, void
|
|||||||
void dns_client_exit(void);
|
void dns_client_exit(void);
|
||||||
|
|
||||||
/* add remote dns server */
|
/* add remote dns server */
|
||||||
int dns_client_add_server(char *server_ip, int port, dns_server_type_t server_type, unsigned int server_flag, unsigned int result_flag, int ttl);
|
int dns_client_add_server(char *server_ip, int port, dns_server_type_t server_type, unsigned int server_flag, unsigned int result_flag, int ttl, char *spki);
|
||||||
|
|
||||||
/* remove remote dns server */
|
/* remove remote dns server */
|
||||||
int dns_client_remove_server(char *server_ip, int port, dns_server_type_t server_type);
|
int dns_client_remove_server(char *server_ip, int port, dns_server_type_t server_type);
|
||||||
|
|||||||
@@ -142,11 +142,14 @@ int config_server(int argc, char *argv[], dns_server_type_t type, int default_po
|
|||||||
int opt = 0;
|
int opt = 0;
|
||||||
unsigned int result_flag = 0;
|
unsigned int result_flag = 0;
|
||||||
unsigned int server_flag = 0;
|
unsigned int server_flag = 0;
|
||||||
|
unsigned char *spki = NULL;
|
||||||
|
|
||||||
int ttl = 0;
|
int ttl = 0;
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{"blacklist-ip", 0, 0, 'b'},
|
{"blacklist-ip", 0, 0, 'b'},
|
||||||
{"check-edns", 0, 0, 'e'},
|
{"check-edns", 0, 0, 'e'},
|
||||||
|
{"spki-pin", required_argument, 0, 'p'},
|
||||||
{"check-ttl", required_argument, 0, 't'},
|
{"check-ttl", required_argument, 0, 't'},
|
||||||
{"group", required_argument, 0, 'g'},
|
{"group", required_argument, 0, 'g'},
|
||||||
{"exclude-default-group", 0, 0, 'E'},
|
{"exclude-default-group", 0, 0, 'E'},
|
||||||
@@ -164,6 +167,7 @@ int config_server(int argc, char *argv[], dns_server_type_t type, int default_po
|
|||||||
}
|
}
|
||||||
|
|
||||||
server = &dns_conf_servers[index];
|
server = &dns_conf_servers[index];
|
||||||
|
server->spki[0] = '\0';
|
||||||
ip = argv[1];
|
ip = argv[1];
|
||||||
|
|
||||||
/* parse ip, port from ip */
|
/* parse ip, port from ip */
|
||||||
@@ -200,7 +204,7 @@ int config_server(int argc, char *argv[], dns_server_type_t type, int default_po
|
|||||||
ttl = atoi(optarg);
|
ttl = atoi(optarg);
|
||||||
if (ttl < -255 || ttl > 255) {
|
if (ttl < -255 || ttl > 255) {
|
||||||
tlog(TLOG_ERROR, "ttl value is invalid.");
|
tlog(TLOG_ERROR, "ttl value is invalid.");
|
||||||
return -1;
|
goto errout;
|
||||||
}
|
}
|
||||||
result_flag |= DNSSERVER_FLAG_CHECK_TTL;
|
result_flag |= DNSSERVER_FLAG_CHECK_TTL;
|
||||||
break;
|
break;
|
||||||
@@ -212,10 +216,14 @@ int config_server(int argc, char *argv[], dns_server_type_t type, int default_po
|
|||||||
case 'g': {
|
case 'g': {
|
||||||
if (dns_conf_get_group_set(optarg, server) != 0) {
|
if (dns_conf_get_group_set(optarg, server) != 0) {
|
||||||
tlog(TLOG_ERROR, "add group failed.");
|
tlog(TLOG_ERROR, "add group failed.");
|
||||||
return -1;
|
goto errout;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'p': {
|
||||||
|
strncpy(server->spki, optarg, DNS_MAX_SPKI_LEN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -230,6 +238,13 @@ int config_server(int argc, char *argv[], dns_server_type_t type, int default_po
|
|||||||
tlog(TLOG_DEBUG, "add server %s, flag: %X, ttl: %d", ip, result_flag, ttl);
|
tlog(TLOG_DEBUG, "add server %s, flag: %X, ttl: %d", ip, result_flag, ttl);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
errout:
|
||||||
|
if (spki) {
|
||||||
|
free(spki);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int config_domain_iter_cb(void *data, const unsigned char *key, uint32_t key_len, void *value)
|
int config_domain_iter_cb(void *data, const unsigned char *key, uint32_t key_len, void *value)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#define DNS_GROUP_NAME_LEN 32
|
#define DNS_GROUP_NAME_LEN 32
|
||||||
#define DNS_NAX_GROUP_NUMBER 16
|
#define DNS_NAX_GROUP_NUMBER 16
|
||||||
#define DNS_MAX_IPLEN 64
|
#define DNS_MAX_IPLEN 64
|
||||||
|
#define DNS_MAX_SPKI_LEN 64
|
||||||
#define DNS_MAX_PATH 1024
|
#define DNS_MAX_PATH 1024
|
||||||
#define DEFAULT_DNS_PORT 53
|
#define DEFAULT_DNS_PORT 53
|
||||||
#define DEFAULT_DNS_TLS_PORT 853
|
#define DEFAULT_DNS_TLS_PORT 853
|
||||||
@@ -91,6 +92,7 @@ struct dns_servers {
|
|||||||
unsigned int server_flag;
|
unsigned int server_flag;
|
||||||
int ttl;
|
int ttl;
|
||||||
dns_server_type_t type;
|
dns_server_type_t type;
|
||||||
|
char spki[DNS_MAX_SPKI_LEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ip address lists of domain */
|
/* ip address lists of domain */
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ int smartdns_add_servers(void)
|
|||||||
|
|
||||||
for (i = 0; i < dns_conf_server_num; i++) {
|
for (i = 0; i < dns_conf_server_num; i++) {
|
||||||
ret = dns_client_add_server(dns_conf_servers[i].server, dns_conf_servers[i].port, dns_conf_servers[i].type, dns_conf_servers[i].server_flag, dns_conf_servers[i].result_flag,
|
ret = dns_client_add_server(dns_conf_servers[i].server, dns_conf_servers[i].port, dns_conf_servers[i].type, dns_conf_servers[i].server_flag, dns_conf_servers[i].result_flag,
|
||||||
dns_conf_servers[i].ttl);
|
dns_conf_servers[i].ttl, dns_conf_servers[i].spki);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
tlog(TLOG_ERROR, "add server failed, %s:%d", dns_conf_servers[i].server, dns_conf_servers[i].port);
|
tlog(TLOG_ERROR, "add server failed, %s:%d", dns_conf_servers[i].server, dns_conf_servers[i].port);
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
38
src/util.c
38
src/util.c
@@ -353,6 +353,44 @@ int ipset_del(const char *ipsetname, const unsigned char addr[], int addr_len)
|
|||||||
return _ipset_operate(ipsetname, addr, addr_len, 0, IPSET_DEL);
|
return _ipset_operate(ipsetname, addr, addr_len, 0, IPSET_DEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char *SSL_SHA256(const unsigned char *d, size_t n, unsigned char *md)
|
||||||
|
{
|
||||||
|
SHA256_CTX c;
|
||||||
|
static unsigned char m[SHA256_DIGEST_LENGTH];
|
||||||
|
|
||||||
|
if (md == NULL)
|
||||||
|
md = m;
|
||||||
|
SHA256_Init(&c);
|
||||||
|
SHA256_Update(&c, d, n);
|
||||||
|
SHA256_Final(md, &c);
|
||||||
|
OPENSSL_cleanse(&c, sizeof(c));
|
||||||
|
return (md);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SSL_base64_decode(const char *in, unsigned char *out)
|
||||||
|
{
|
||||||
|
size_t inlen = strlen(in);
|
||||||
|
int outlen;
|
||||||
|
|
||||||
|
if (inlen == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
outlen = EVP_DecodeBlock(out, (unsigned char *)in, inlen);
|
||||||
|
if (outlen < 0) {
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Subtract padding bytes from |outlen| */
|
||||||
|
while (in[--inlen] == '=') {
|
||||||
|
--outlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return outlen;
|
||||||
|
errout:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#define THREAD_STACK_SIZE (16*1024)
|
#define THREAD_STACK_SIZE (16*1024)
|
||||||
static pthread_mutex_t *lock_cs;
|
static pthread_mutex_t *lock_cs;
|
||||||
static long *lock_count;
|
static long *lock_count;
|
||||||
|
|||||||
@@ -30,4 +30,8 @@ void SSL_CRYPTO_thread_setup(void);
|
|||||||
|
|
||||||
void SSL_CRYPTO_thread_cleanup(void);
|
void SSL_CRYPTO_thread_cleanup(void);
|
||||||
|
|
||||||
|
unsigned char *SSL_SHA256(const unsigned char *d, size_t n, unsigned char *md);
|
||||||
|
|
||||||
|
int SSL_base64_decode(const char *in, unsigned char *out);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user