GeoIP Info implemented
This commit is contained in:
4
Makefile
4
Makefile
@ -7,11 +7,11 @@ packages:
|
|||||||
|
|
||||||
compile:
|
compile:
|
||||||
@mkdir -p bin
|
@mkdir -p bin
|
||||||
gcc src/necronda-server.c -o bin/necronda-server -std=c11 -lssl -lcrypto -lmagic -lz
|
gcc src/necronda-server.c -o bin/necronda-server -std=c11 -lssl -lcrypto -lmagic -lz -lmaxminddb
|
||||||
|
|
||||||
compile-debian:
|
compile-debian:
|
||||||
@mkdir -p bin
|
@mkdir -p bin
|
||||||
gcc src/necronda-server.c -o bin/necronda-server -std=c11 -lssl -lcrypto -lmagic -lz \
|
gcc src/necronda-server.c -o bin/necronda-server -std=c11 -lssl -lcrypto -lmagic -lz -lmaxminddb \
|
||||||
-D MAGIC_FILE="\"/usr/share/file/magic.mgc\"" \
|
-D MAGIC_FILE="\"/usr/share/file/magic.mgc\"" \
|
||||||
-D PHP_FPM_SOCKET="\"/var/run/php/php7.3-fpm.sock\""
|
-D PHP_FPM_SOCKET="\"/var/run/php/php7.3-fpm.sock\""
|
||||||
|
|
||||||
|
52
src/client.c
52
src/client.c
@ -15,7 +15,7 @@
|
|||||||
int server_keep_alive = 1;
|
int server_keep_alive = 1;
|
||||||
char *client_addr_str, *client_addr_str_ptr, *server_addr_str, *server_addr_str_ptr,
|
char *client_addr_str, *client_addr_str_ptr, *server_addr_str, *server_addr_str_ptr,
|
||||||
*log_client_prefix, *log_conn_prefix, *log_req_prefix,
|
*log_client_prefix, *log_conn_prefix, *log_req_prefix,
|
||||||
*client_host_str;
|
*client_host_str, *client_geoip;
|
||||||
|
|
||||||
struct timeval client_timeout = {.tv_sec = CLIENT_TIMEOUT, .tv_usec = 0};
|
struct timeval client_timeout = {.tv_sec = CLIENT_TIMEOUT, .tv_usec = 0};
|
||||||
|
|
||||||
@ -460,10 +460,56 @@ int client_connection_handler(sock *client, unsigned long client_num) {
|
|||||||
client_host_str = NULL;
|
client_host_str = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO get geoip data for ip address
|
client_geoip = malloc(GEOIP_MAX_SIZE);
|
||||||
|
long str_off = 0;
|
||||||
|
for (int i = 0; i < MAX_MMDB && mmdbs[i].filename != NULL; i++) {
|
||||||
|
int gai_error, mmdb_res;
|
||||||
|
MMDB_lookup_result_s result = MMDB_lookup_string(&mmdbs[i], "62.47.28.246", &gai_error, &mmdb_res);
|
||||||
|
if (mmdb_res != MMDB_SUCCESS) {
|
||||||
|
print(ERR_STR "Unable to lookup geoip info: %s" CLR_STR "\n", MMDB_strerror(mmdb_res));
|
||||||
|
continue;
|
||||||
|
} else if (gai_error != 0) {
|
||||||
|
print(ERR_STR "Unable to lookup geoip info" CLR_STR "\n");
|
||||||
|
continue;
|
||||||
|
} else if (!result.found_entry) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
MMDB_entry_data_list_s *list;
|
||||||
|
mmdb_res = MMDB_get_entry_data_list(&result.entry, &list);
|
||||||
|
if (mmdb_res != MMDB_SUCCESS) {
|
||||||
|
print(ERR_STR "Unable to lookup geoip info: %s" CLR_STR "\n", MMDB_strerror(mmdb_res));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
long prev = str_off;
|
||||||
|
if (str_off != 0) {
|
||||||
|
str_off--;
|
||||||
|
}
|
||||||
|
mmdb_json(list, client_geoip, &str_off, GEOIP_MAX_SIZE);
|
||||||
|
if (prev != 0) {
|
||||||
|
client_geoip[prev - 1] = ',';
|
||||||
|
}
|
||||||
|
|
||||||
|
MMDB_free_entry_data_list(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
char client_cc[3];
|
||||||
|
client_cc[0] = 0;
|
||||||
|
if (str_off == 0) {
|
||||||
|
free(client_geoip);
|
||||||
|
client_geoip = NULL;
|
||||||
|
} else {
|
||||||
|
char *pos = strstr(client_geoip, "\"iso_code\":\"");
|
||||||
|
if (pos != NULL) {
|
||||||
|
pos += 12;
|
||||||
|
strncpy(client_cc, pos, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
print("Connection accepted from %s %s%s%s[%s]", client_addr_str, client_host_str != NULL ? "(" : "",
|
print("Connection accepted from %s %s%s%s[%s]", client_addr_str, client_host_str != NULL ? "(" : "",
|
||||||
client_host_str != NULL ? client_host_str : "", client_host_str != NULL ? ") " : "", "N/A");
|
client_host_str != NULL ? client_host_str : "", client_host_str != NULL ? ") " : "",
|
||||||
|
client_cc[0] != 0 ? client_cc : "N/A");
|
||||||
|
|
||||||
client_timeout.tv_sec = CLIENT_TIMEOUT;
|
client_timeout.tv_sec = CLIENT_TIMEOUT;
|
||||||
client_timeout.tv_usec = 0;
|
client_timeout.tv_usec = 0;
|
||||||
|
@ -142,6 +142,9 @@ int fastcgi_init(fastcgi_conn *conn, unsigned int client_num, unsigned int req_n
|
|||||||
param_ptr = fastcgi_add_param(param_ptr, "CONTENT_LENGTH", content_length != NULL ? content_length : "");
|
param_ptr = fastcgi_add_param(param_ptr, "CONTENT_LENGTH", content_length != NULL ? content_length : "");
|
||||||
char *content_type = http_get_header_field(&req->hdr, "Content-Type");
|
char *content_type = http_get_header_field(&req->hdr, "Content-Type");
|
||||||
param_ptr = fastcgi_add_param(param_ptr, "CONTENT_TYPE", content_type != NULL ? content_type : "");
|
param_ptr = fastcgi_add_param(param_ptr, "CONTENT_TYPE", content_type != NULL ? content_type : "");
|
||||||
|
if (client_geoip != NULL) {
|
||||||
|
param_ptr = fastcgi_add_param(param_ptr, "REMOTE_INFO", client_geoip);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < req->hdr.field_num; i++) {
|
for (int i = 0; i < req->hdr.field_num; i++) {
|
||||||
char *ptr = buf0;
|
char *ptr = buf0;
|
||||||
|
@ -172,6 +172,10 @@ int main(int argc, const char *argv[]) {
|
|||||||
struct sockaddr_in6 client_addr;
|
struct sockaddr_in6 client_addr;
|
||||||
unsigned int client_addr_len = sizeof(client_addr);
|
unsigned int client_addr_len = sizeof(client_addr);
|
||||||
|
|
||||||
|
memset(sockets, 0, sizeof(sockets));
|
||||||
|
memset(children, 0, sizeof(children));
|
||||||
|
memset(mmdbs, 0, sizeof(mmdbs));
|
||||||
|
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
|
|
||||||
const struct sockaddr_in6 addresses[2] = {
|
const struct sockaddr_in6 addresses[2] = {
|
||||||
@ -189,12 +193,12 @@ int main(int argc, const char *argv[]) {
|
|||||||
const char *arg = argv[i];
|
const char *arg = argv[i];
|
||||||
unsigned long len = strlen(arg);
|
unsigned long len = strlen(arg);
|
||||||
if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
|
if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
|
||||||
printf("Usage: necronda-server [-h] -w <PATH> -c <CERT-FILE> -p <KEY-FILE> [-g <DB-FILE>] [-d <DNS-SERVER>]\n"
|
printf("Usage: necronda-server [-h] -w <PATH> -c <CERT-FILE> -p <KEY-FILE> [-g <DB-DIR>] [-d <DNS-SERVER>]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
" -c, --cert <CERT-FILE> path to the full chain certificate file\n"
|
" -c, --cert <CERT-FILE> path to the full chain certificate file\n"
|
||||||
" -d, --dns <DNS-SERVER> ip address or hostname of a DNS server for dig\n"
|
" -d, --dns <DNS-SERVER> ip address or hostname of a DNS server for dig\n"
|
||||||
" -g, --geoip <DB-FILE> path to a Maxmind GeoIP Database file\n"
|
" -g, --geoip <DB-DIR> path to a Maxmind GeoIP Database file\n"
|
||||||
" -h, --help print this dialogue\n"
|
" -h, --help print this dialogue\n"
|
||||||
" -p, --privkey <KEY-FILE> path to the private key file\n"
|
" -p, --privkey <KEY-FILE> path to the private key file\n"
|
||||||
" -w, --webroot <PATH> path to the web root directory\n");
|
" -w, --webroot <PATH> path to the web root directory\n");
|
||||||
@ -219,10 +223,10 @@ int main(int argc, const char *argv[]) {
|
|||||||
key_file = argv[++i];
|
key_file = argv[++i];
|
||||||
} else if (strcmp(arg, "-g") == 0 || strcmp(arg, "--geoip") == 0) {
|
} else if (strcmp(arg, "-g") == 0 || strcmp(arg, "--geoip") == 0) {
|
||||||
if (i == argc - 1) {
|
if (i == argc - 1) {
|
||||||
fprintf(stderr, ERR_STR "Unable to parse argument %s, usage: --geoip <DB-FILE>" CLR_STR "\n", arg);
|
fprintf(stderr, ERR_STR "Unable to parse argument %s, usage: --geoip <DB-DIR>" CLR_STR "\n", arg);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
geoip_file = argv[++i];
|
geoip_dir = argv[++i];
|
||||||
} else if (strcmp(arg, "-d") == 0 || strcmp(arg, "--dns") == 0) {
|
} else if (strcmp(arg, "-d") == 0 || strcmp(arg, "--dns") == 0) {
|
||||||
if (i == argc - 1) {
|
if (i == argc - 1) {
|
||||||
fprintf(stderr, ERR_STR "Unable to parse argument %s, usage: --dns <DNS-SERVER>" CLR_STR "\n", arg);
|
fprintf(stderr, ERR_STR "Unable to parse argument %s, usage: --dns <DNS-SERVER>" CLR_STR "\n", arg);
|
||||||
@ -274,14 +278,34 @@ int main(int argc, const char *argv[]) {
|
|||||||
signal(SIGINT, terminate);
|
signal(SIGINT, terminate);
|
||||||
signal(SIGTERM, terminate);
|
signal(SIGTERM, terminate);
|
||||||
|
|
||||||
ret = cache_init();
|
if (geoip_dir != NULL) {
|
||||||
if (ret < 0) {
|
DIR *geoip = opendir(geoip_dir);
|
||||||
|
if (geoip == NULL) {
|
||||||
|
fprintf(stderr, ERR_STR "Unable to open GeoIP dir: %s" CLR_STR "\n", strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
} else if (ret != 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
struct dirent *dir;
|
||||||
// TODO init geoip database
|
int i = 0;
|
||||||
|
while ((dir = readdir(geoip)) != NULL) {
|
||||||
|
if (strcmp(dir->d_name + strlen(dir->d_name) - 5, ".mmdb") != 0) continue;
|
||||||
|
if (i >= MAX_MMDB) {
|
||||||
|
fprintf(stderr, ERR_STR "Too many .mmdb files" CLR_STR "\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
sprintf(buf, "%s/%s", geoip_dir, dir->d_name);
|
||||||
|
ret = MMDB_open(buf, 0, &mmdbs[i]);
|
||||||
|
if (ret != MMDB_SUCCESS) {
|
||||||
|
fprintf(stderr, ERR_STR "Unable to open .mmdb file: %s" CLR_STR "\n", MMDB_strerror(ret));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i == 0) {
|
||||||
|
fprintf(stderr, ERR_STR "No .mmdb files found in %s" CLR_STR "\n", geoip_dir);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
closedir(geoip);
|
||||||
|
}
|
||||||
|
|
||||||
openssl_init();
|
openssl_init();
|
||||||
|
|
||||||
@ -322,6 +346,13 @@ int main(int argc, const char *argv[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = cache_init();
|
||||||
|
if (ret < 0) {
|
||||||
|
return 1;
|
||||||
|
} else if (ret != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(stderr, "Ready to accept connections\n");
|
fprintf(stderr, "Ready to accept connections\n");
|
||||||
|
|
||||||
while (active) {
|
while (active) {
|
||||||
|
@ -25,10 +25,13 @@
|
|||||||
#include <openssl/conf.h>
|
#include <openssl/conf.h>
|
||||||
#include <openssl/engine.h>
|
#include <openssl/engine.h>
|
||||||
#include <openssl/dh.h>
|
#include <openssl/dh.h>
|
||||||
|
#include <maxminddb.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
|
||||||
#define NUM_SOCKETS 2
|
#define NUM_SOCKETS 2
|
||||||
#define MAX_CHILDREN 1024
|
#define MAX_CHILDREN 1024
|
||||||
|
#define MAX_MMDB 3
|
||||||
#define LISTEN_BACKLOG 16
|
#define LISTEN_BACKLOG 16
|
||||||
#define REQ_PER_CONNECTION 100
|
#define REQ_PER_CONNECTION 100
|
||||||
#define CLIENT_TIMEOUT 3600
|
#define CLIENT_TIMEOUT 3600
|
||||||
@ -37,6 +40,7 @@
|
|||||||
#define CLIENT_MAX_HEADER_SIZE 8192
|
#define CLIENT_MAX_HEADER_SIZE 8192
|
||||||
#define FILE_CACHE_SIZE 1024
|
#define FILE_CACHE_SIZE 1024
|
||||||
#define SHM_KEY 255641
|
#define SHM_KEY 255641
|
||||||
|
#define GEOIP_MAX_SIZE 8192
|
||||||
|
|
||||||
#define ERR_STR "\x1B[1;31m"
|
#define ERR_STR "\x1B[1;31m"
|
||||||
#define CLR_STR "\x1B[0m"
|
#define CLR_STR "\x1B[0m"
|
||||||
@ -67,8 +71,9 @@
|
|||||||
|
|
||||||
int sockets[NUM_SOCKETS];
|
int sockets[NUM_SOCKETS];
|
||||||
pid_t children[MAX_CHILDREN];
|
pid_t children[MAX_CHILDREN];
|
||||||
|
MMDB_s mmdbs[MAX_MMDB];
|
||||||
|
|
||||||
const char *cert_file, *key_file, *webroot_base, *geoip_file, *dns_server;
|
const char *cert_file, *key_file, *webroot_base, *geoip_dir, *dns_server;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int enc:1;
|
unsigned int enc:1;
|
||||||
|
61
src/utils.c
61
src/utils.c
@ -94,3 +94,64 @@ int url_decode(const char *str, char *dec, ssize_t *size) {
|
|||||||
*size = ptr - dec;
|
*size = ptr - dec;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MMDB_entry_data_list_s *mmdb_json(MMDB_entry_data_list_s *list, char *str, long *str_off, long str_len) {
|
||||||
|
switch (list->entry_data.type) {
|
||||||
|
case MMDB_DATA_TYPE_MAP:
|
||||||
|
*str_off += sprintf(str + *str_off, "{");
|
||||||
|
break;
|
||||||
|
case MMDB_DATA_TYPE_ARRAY:
|
||||||
|
*str_off += sprintf(str + *str_off, "[");
|
||||||
|
break;
|
||||||
|
case MMDB_DATA_TYPE_UTF8_STRING:
|
||||||
|
*str_off += sprintf(str + *str_off, "\"%.*s\"", list->entry_data.data_size, list->entry_data.utf8_string);
|
||||||
|
break;
|
||||||
|
case MMDB_DATA_TYPE_UINT16:
|
||||||
|
*str_off += sprintf(str + *str_off, "%u", list->entry_data.uint16);
|
||||||
|
break;
|
||||||
|
case MMDB_DATA_TYPE_UINT32:
|
||||||
|
*str_off += sprintf(str + *str_off, "%u", list->entry_data.uint32);
|
||||||
|
break;
|
||||||
|
case MMDB_DATA_TYPE_UINT64:
|
||||||
|
*str_off += sprintf(str + *str_off, "%lu", list->entry_data.uint64);
|
||||||
|
break;
|
||||||
|
case MMDB_DATA_TYPE_UINT128:
|
||||||
|
*str_off += sprintf(str + *str_off, "%llu", list->entry_data.uint128);
|
||||||
|
break;
|
||||||
|
case MMDB_DATA_TYPE_INT32:
|
||||||
|
*str_off += sprintf(str + *str_off, "%i", list->entry_data.uint32);
|
||||||
|
break;
|
||||||
|
case MMDB_DATA_TYPE_BOOLEAN:
|
||||||
|
*str_off += sprintf(str + *str_off, "%s", list->entry_data.boolean ? "true" : "false");
|
||||||
|
break;
|
||||||
|
case MMDB_DATA_TYPE_FLOAT:
|
||||||
|
*str_off += sprintf(str + *str_off, "%f", list->entry_data.float_value);
|
||||||
|
break;
|
||||||
|
case MMDB_DATA_TYPE_DOUBLE:
|
||||||
|
*str_off += sprintf(str + *str_off, "%f", list->entry_data.double_value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (list->entry_data.type != MMDB_DATA_TYPE_MAP && list->entry_data.type != MMDB_DATA_TYPE_ARRAY) {
|
||||||
|
return list->next;
|
||||||
|
}
|
||||||
|
MMDB_entry_data_list_s *next = list->next;
|
||||||
|
int stat = 0;
|
||||||
|
for (int i = 0; i < list->entry_data.data_size; i++) {
|
||||||
|
next = mmdb_json(next, str, str_off, str_len);
|
||||||
|
if (list->entry_data.type == MMDB_DATA_TYPE_MAP) {
|
||||||
|
stat = !stat;
|
||||||
|
if (stat) {
|
||||||
|
i--;
|
||||||
|
*str_off += sprintf(str + *str_off, ":");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i != list->entry_data.data_size - 1) *str_off += sprintf(str + *str_off, ",");
|
||||||
|
}
|
||||||
|
if (list->entry_data.type == MMDB_DATA_TYPE_MAP) {
|
||||||
|
*str_off += sprintf(str + *str_off, "}");
|
||||||
|
} else {
|
||||||
|
*str_off += sprintf(str + *str_off, "]");
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user