smartdns.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. /*************************************************************************
  2. *
  3. * Copyright (C) 2018-2020 Ruilin Peng (Nick) <[email protected]>.
  4. *
  5. * smartdns is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * smartdns is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #define _GNU_SOURCE
  19. #include "art.h"
  20. #include "atomic.h"
  21. #include "dns_client.h"
  22. #include "dns_conf.h"
  23. #include "dns_server.h"
  24. #include "fast_ping.h"
  25. #include "hashtable.h"
  26. #include "list.h"
  27. #include "rbtree.h"
  28. #include "tlog.h"
  29. #include "util.h"
  30. #include <errno.h>
  31. #include <fcntl.h>
  32. #include <libgen.h>
  33. #include <linux/capability.h>
  34. #include <openssl/err.h>
  35. #include <openssl/ssl.h>
  36. #include <pwd.h>
  37. #include <signal.h>
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include <sys/prctl.h>
  42. #include <sys/stat.h>
  43. #include <sys/types.h>
  44. #include <ucontext.h>
  45. #define RESOLVE_FILE "/etc/resolv.conf"
  46. #define MAX_LINE_LEN 1024
  47. #define MAX_KEY_LEN 64
  48. #define SMARTDNS_PID_FILE "/var/run/smartdns.pid"
  49. #define TMP_BUFF_LEN_32 32
  50. static int verbose_screen;
  51. int capget(struct __user_cap_header_struct *header, struct __user_cap_data_struct *cap);
  52. int capset(struct __user_cap_header_struct *header, struct __user_cap_data_struct *cap);
  53. static int get_uid_gid(int *uid, int *gid)
  54. {
  55. struct passwd *result = NULL;
  56. struct passwd pwd;
  57. char *buf = NULL;
  58. ssize_t bufsize = 0;
  59. int ret = -1;
  60. if (dns_conf_user[0] == '\0') {
  61. return -1;
  62. }
  63. bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
  64. if (bufsize == -1) {
  65. bufsize = 1024 * 16;
  66. }
  67. buf = malloc(bufsize);
  68. if (buf == NULL) {
  69. goto out;
  70. }
  71. ret = getpwnam_r(dns_conf_user, &pwd, buf, bufsize, &result);
  72. if (ret != 0) {
  73. goto out;
  74. }
  75. *uid = result->pw_uid;
  76. *gid = result->pw_gid;
  77. out:
  78. if (buf) {
  79. free(buf);
  80. }
  81. return ret;
  82. }
  83. static int drop_root_privilege(void)
  84. {
  85. struct __user_cap_data_struct cap;
  86. struct __user_cap_header_struct header;
  87. header.version = _LINUX_CAPABILITY_VERSION;
  88. header.pid = 0;
  89. int uid = 0;
  90. int gid = 0;
  91. int unused __attribute__((unused)) = 0;
  92. if (get_uid_gid(&uid, &gid) != 0) {
  93. return -1;
  94. }
  95. if (capget(&header, &cap) < 0) {
  96. return -1;
  97. }
  98. prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
  99. cap.effective |= (1 << CAP_NET_RAW | 1 << CAP_NET_ADMIN);
  100. cap.permitted |= (1 << CAP_NET_RAW | 1 << CAP_NET_ADMIN);
  101. unused = setuid(uid);
  102. unused = setgid(gid);
  103. if (capset(&header, &cap) < 0) {
  104. return -1;
  105. }
  106. prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0);
  107. return 0;
  108. }
  109. static void _help(void)
  110. {
  111. /* clang-format off */
  112. char *help = ""
  113. "Usage: smartdns [OPTION]...\n"
  114. "Start smartdns server.\n"
  115. " -f run forground.\n"
  116. " -c [conf] config file.\n"
  117. " -p [pid] pid file path\n"
  118. " -S ignore segment fault signal.\n"
  119. " -x verbose screen.\n"
  120. " -v dispaly version.\n"
  121. " -h show this help message.\n"
  122. "Online help: http://pymumu.github.io/smartdns\n"
  123. "Copyright (C) Nick Peng <[email protected]>\n"
  124. ;
  125. /* clang-format on */
  126. printf("%s", help);
  127. }
  128. static void _show_version(void)
  129. {
  130. char str_ver[256] = {0};
  131. #ifdef SMARTDNS_VERION
  132. const char *ver = SMARTDNS_VERION;
  133. snprintf(str_ver, sizeof(str_ver), "%s", ver);
  134. #else
  135. struct tm tm;
  136. get_compiled_time(&tm);
  137. snprintf(str_ver, sizeof(str_ver), "1.%.4d%.2d%.2d-%.2d%.2d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
  138. tm.tm_hour, tm.tm_min);
  139. #endif
  140. printf("smartdns %s\n", str_ver);
  141. }
  142. static int _smartdns_load_from_resolv(void)
  143. {
  144. FILE *fp = NULL;
  145. char line[MAX_LINE_LEN];
  146. char key[MAX_KEY_LEN];
  147. char value[MAX_LINE_LEN];
  148. char ns_ip[DNS_MAX_IPLEN];
  149. int port = PORT_NOT_DEFINED;
  150. int ret = -1;
  151. int filed_num = 0;
  152. int line_num = 0;
  153. fp = fopen(RESOLVE_FILE, "r");
  154. if (fp == NULL) {
  155. tlog(TLOG_ERROR, "open %s failed, %s", RESOLVE_FILE, strerror(errno));
  156. return -1;
  157. }
  158. while (fgets(line, MAX_LINE_LEN, fp)) {
  159. line_num++;
  160. filed_num = sscanf(line, "%63s %1023[^\r\n]s", key, value);
  161. if (filed_num != 2) {
  162. continue;
  163. }
  164. if (strncmp(key, "nameserver", MAX_KEY_LEN - 1) != 0) {
  165. continue;
  166. }
  167. if (parse_ip(value, ns_ip, &port) != 0) {
  168. continue;
  169. }
  170. if (port == PORT_NOT_DEFINED) {
  171. port = DEFAULT_DNS_PORT;
  172. }
  173. safe_strncpy(dns_conf_servers[dns_conf_server_num].server, ns_ip, DNS_MAX_IPLEN);
  174. dns_conf_servers[dns_conf_server_num].port = port;
  175. dns_conf_servers[dns_conf_server_num].type = DNS_SERVER_UDP;
  176. dns_conf_server_num++;
  177. ret = 0;
  178. }
  179. fclose(fp);
  180. return ret;
  181. }
  182. static int _smartdns_add_servers(void)
  183. {
  184. unsigned long i = 0;
  185. int j = 0;
  186. int ret = 0;
  187. struct dns_server_groups *group = NULL;
  188. struct dns_servers *server = NULL;
  189. struct client_dns_server_flags flags;
  190. for (i = 0; i < (unsigned int)dns_conf_server_num; i++) {
  191. memset(&flags, 0, sizeof(flags));
  192. switch (dns_conf_servers[i].type) {
  193. case DNS_SERVER_UDP: {
  194. struct client_dns_server_flag_udp *flag_udp = &flags.udp;
  195. flag_udp->ttl = dns_conf_servers[i].ttl;
  196. } break;
  197. case DNS_SERVER_HTTPS: {
  198. struct client_dns_server_flag_https *flag_http = &flags.https;
  199. flag_http->spi_len = dns_client_spki_decode(dns_conf_servers[i].spki, (unsigned char *)flag_http->spki);
  200. safe_strncpy(flag_http->hostname, dns_conf_servers[i].hostname, sizeof(flag_http->hostname));
  201. safe_strncpy(flag_http->path, dns_conf_servers[i].path, sizeof(flag_http->path));
  202. safe_strncpy(flag_http->httphost, dns_conf_servers[i].httphost, sizeof(flag_http->httphost));
  203. safe_strncpy(flag_http->tls_host_verify, dns_conf_servers[i].tls_host_verify,
  204. sizeof(flag_http->tls_host_verify));
  205. flag_http->skip_check_cert = dns_conf_servers[i].skip_check_cert;
  206. } break;
  207. case DNS_SERVER_TLS: {
  208. struct client_dns_server_flag_tls *flag_tls = &flags.tls;
  209. flag_tls->spi_len = dns_client_spki_decode(dns_conf_servers[i].spki, (unsigned char *)flag_tls->spki);
  210. safe_strncpy(flag_tls->hostname, dns_conf_servers[i].hostname, sizeof(flag_tls->hostname));
  211. safe_strncpy(flag_tls->tls_host_verify, dns_conf_servers[i].tls_host_verify,
  212. sizeof(flag_tls->tls_host_verify));
  213. flag_tls->skip_check_cert = dns_conf_servers[i].skip_check_cert;
  214. } break;
  215. case DNS_SERVER_TCP:
  216. break;
  217. default:
  218. return -1;
  219. break;
  220. }
  221. flags.type = dns_conf_servers[i].type;
  222. flags.server_flag = dns_conf_servers[i].server_flag;
  223. flags.result_flag = dns_conf_servers[i].result_flag;
  224. ret = dns_client_add_server(dns_conf_servers[i].server, dns_conf_servers[i].port, dns_conf_servers[i].type,
  225. &flags);
  226. if (ret != 0) {
  227. tlog(TLOG_ERROR, "add server failed, %s:%d", dns_conf_servers[i].server, dns_conf_servers[i].port);
  228. return -1;
  229. }
  230. }
  231. hash_for_each(dns_group_table.group, i, group, node)
  232. {
  233. ret = dns_client_add_group(group->group_name);
  234. if (ret != 0) {
  235. tlog(TLOG_ERROR, "add group failed, %s", group->group_name);
  236. return -1;
  237. }
  238. for (j = 0; j < group->server_num; j++) {
  239. server = group->servers[j];
  240. if (server == NULL) {
  241. continue;
  242. }
  243. ret = dns_client_add_to_group(group->group_name, server->server, server->port, server->type);
  244. if (ret != 0) {
  245. tlog(TLOG_ERROR, "add server %s to group %s failed", server->server, group->group_name);
  246. return -1;
  247. }
  248. }
  249. }
  250. return 0;
  251. }
  252. static int _smartdns_set_ecs_ip(void)
  253. {
  254. int ret = 0;
  255. if (dns_conf_ipv4_ecs.enable) {
  256. ret |= dns_client_set_ecs(dns_conf_ipv4_ecs.ip, dns_conf_ipv4_ecs.subnet);
  257. }
  258. if (dns_conf_ipv6_ecs.enable) {
  259. ret |= dns_client_set_ecs(dns_conf_ipv6_ecs.ip, dns_conf_ipv6_ecs.subnet);
  260. }
  261. return ret;
  262. }
  263. static int _smartdns_init_ssl(void)
  264. {
  265. #if OPENSSL_API_COMPAT < 0x10100000L
  266. SSL_load_error_strings();
  267. SSL_library_init();
  268. OpenSSL_add_all_algorithms();
  269. SSL_CRYPTO_thread_setup();
  270. #endif
  271. return 0;
  272. }
  273. static int _smartdns_destroy_ssl(void)
  274. {
  275. #if OPENSSL_API_COMPAT < 0x10100000L
  276. SSL_CRYPTO_thread_cleanup();
  277. ERR_free_strings();
  278. EVP_cleanup();
  279. #endif
  280. return 0;
  281. }
  282. static int _smartdns_init(void)
  283. {
  284. int ret = 0;
  285. char *logfile = SMARTDNS_LOG_FILE;
  286. if (dns_conf_log_file[0] != 0) {
  287. logfile = dns_conf_log_file;
  288. }
  289. ret = tlog_init(logfile, dns_conf_log_size, dns_conf_log_num, 0, 0);
  290. if (ret != 0) {
  291. tlog(TLOG_ERROR, "start tlog failed.\n");
  292. goto errout;
  293. }
  294. tlog_setlogscreen(verbose_screen);
  295. tlog_setlevel(dns_conf_log_level);
  296. tlog(TLOG_NOTICE, "smartdns starting...(Copyright (C) Nick Peng <[email protected]>, build:%s %s)", __DATE__,
  297. __TIME__);
  298. if (_smartdns_init_ssl() != 0) {
  299. tlog(TLOG_ERROR, "init ssl failed.");
  300. goto errout;
  301. }
  302. if (dns_conf_server_num <= 0) {
  303. if (_smartdns_load_from_resolv() != 0) {
  304. tlog(TLOG_ERROR, "load dns from resolv failed.");
  305. goto errout;
  306. }
  307. }
  308. ret = fast_ping_init();
  309. if (ret != 0) {
  310. tlog(TLOG_ERROR, "start ping failed.\n");
  311. goto errout;
  312. }
  313. ret = dns_server_init();
  314. if (ret != 0) {
  315. tlog(TLOG_ERROR, "start dns server failed.\n");
  316. goto errout;
  317. }
  318. ret = dns_client_init();
  319. if (ret != 0) {
  320. tlog(TLOG_ERROR, "start dns client failed.\n");
  321. goto errout;
  322. }
  323. ret = _smartdns_add_servers();
  324. if (ret != 0) {
  325. tlog(TLOG_ERROR, "add servers failed.");
  326. goto errout;
  327. }
  328. ret = _smartdns_set_ecs_ip();
  329. if (ret != 0) {
  330. tlog(TLOG_WARN, "set ecs ip address failed.");
  331. }
  332. return 0;
  333. errout:
  334. return -1;
  335. }
  336. static int _smartdns_run(void)
  337. {
  338. return dns_server_run();
  339. }
  340. static void _smartdns_exit(void)
  341. {
  342. tlog(TLOG_INFO, "smartdns exit...");
  343. dns_client_exit();
  344. fast_ping_exit();
  345. dns_server_exit();
  346. _smartdns_destroy_ssl();
  347. tlog_exit();
  348. dns_server_load_exit();
  349. }
  350. static void _sig_exit(int signo)
  351. {
  352. tlog(TLOG_INFO, "stop smartdns by signal %d", signo);
  353. dns_server_stop();
  354. }
  355. static void _sig_error_exit(int signo, siginfo_t *siginfo, void *ct)
  356. {
  357. unsigned long PC = 0;
  358. ucontext_t *context = ct;
  359. const char *arch = NULL;
  360. #if defined(__i386__)
  361. int *pgregs = (int *)(&(context->uc_mcontext.gregs));
  362. PC = pgregs[REG_EIP];
  363. arch = "i386";
  364. #elif defined(__x86_64__)
  365. int *pgregs = (int *)(&(context->uc_mcontext.gregs));
  366. PC = pgregs[REG_RIP];
  367. arch = "x86_64";
  368. #elif defined(__arm__)
  369. PC = context->uc_mcontext.arm_pc;
  370. arch = "arm";
  371. #elif defined(__aarch64__)
  372. PC = context->uc_mcontext.pc;
  373. arch = "arm64";
  374. #elif defined(__mips__)
  375. PC = context->uc_mcontext.pc;
  376. arch = "mips";
  377. #endif
  378. tlog(TLOG_FATAL,
  379. "process exit with signal %d, code = %d, errno = %d, pid = %d, self = %d, pc = %#lx, addr = %#lx, build(%s "
  380. "%s %s)\n",
  381. signo, siginfo->si_code, siginfo->si_errno, siginfo->si_pid, getpid(), PC, (unsigned long)siginfo->si_addr,
  382. __DATE__, __TIME__, arch);
  383. print_stack();
  384. sleep(1);
  385. _exit(0);
  386. }
  387. static int sig_list[] = {SIGSEGV, SIGABRT, SIGBUS, SIGILL, SIGFPE};
  388. static int sig_num = sizeof(sig_list) / sizeof(int);
  389. static void _reg_signal(void)
  390. {
  391. struct sigaction act;
  392. struct sigaction old;
  393. int i = 0;
  394. act.sa_sigaction = _sig_error_exit;
  395. sigemptyset(&act.sa_mask);
  396. act.sa_flags = SA_RESTART | SA_SIGINFO;
  397. for (i = 0; i < sig_num; i++) {
  398. sigaction(sig_list[i], &act, &old);
  399. }
  400. }
  401. int main(int argc, char *argv[])
  402. {
  403. int ret = 0;
  404. int is_forground = 0;
  405. int opt = 0;
  406. char config_file[MAX_LINE_LEN];
  407. char pid_file[MAX_LINE_LEN];
  408. int signal_ignore = 0;
  409. sigset_t empty_sigblock;
  410. safe_strncpy(config_file, SMARTDNS_CONF_FILE, MAX_LINE_LEN);
  411. safe_strncpy(pid_file, SMARTDNS_PID_FILE, MAX_LINE_LEN);
  412. /* patch for Asus router: unblock all signal*/
  413. sigemptyset(&empty_sigblock);
  414. sigprocmask(SIG_SETMASK, &empty_sigblock, NULL);
  415. while ((opt = getopt(argc, argv, "fhc:p:Svx")) != -1) {
  416. switch (opt) {
  417. case 'f':
  418. is_forground = 1;
  419. break;
  420. case 'c':
  421. snprintf(config_file, sizeof(config_file), "%s", optarg);
  422. break;
  423. case 'p':
  424. snprintf(pid_file, sizeof(pid_file), "%s", optarg);
  425. break;
  426. case 'S':
  427. signal_ignore = 1;
  428. break;
  429. case 'x':
  430. verbose_screen = 1;
  431. break;
  432. case 'v':
  433. _show_version();
  434. return 0;
  435. break;
  436. case 'h':
  437. _help();
  438. return 1;
  439. }
  440. }
  441. if (dns_server_load_conf(config_file) != 0) {
  442. fprintf(stderr, "load config failed.\n");
  443. goto errout;
  444. }
  445. if (is_forground == 0) {
  446. if (daemon(0, 0) < 0) {
  447. fprintf(stderr, "run daemon process failed, %s\n", strerror(errno));
  448. return 1;
  449. }
  450. }
  451. if (signal_ignore == 0) {
  452. _reg_signal();
  453. }
  454. if (create_pid_file(pid_file) != 0) {
  455. goto errout;
  456. }
  457. signal(SIGPIPE, SIG_IGN);
  458. signal(SIGINT, _sig_exit);
  459. signal(SIGTERM, _sig_exit);
  460. drop_root_privilege();
  461. ret = _smartdns_init();
  462. if (ret != 0) {
  463. usleep(100000);
  464. goto errout;
  465. }
  466. atexit(_smartdns_exit);
  467. return _smartdns_run();
  468. errout:
  469. return 1;
  470. }