diff --git a/doc/RELEASE-NOTES.md b/doc/RELEASE-NOTES.md index 3a2219811..08ede18c2 100644 --- a/doc/RELEASE-NOTES.md +++ b/doc/RELEASE-NOTES.md @@ -81,6 +81,12 @@ You can help us by testing this release and reporting any issues at https://bugs * New module `whowasdb` (persistent `WHOWAS` history): this saves the WHOWAS history on disk periodically and when we terminate, so next server boot still has the WHOWAS history. This module is currently not loaded by default. +* New option [listen::spoof-ip](https://www.unrealircd.org/docs/Listen_block#spoof-ip), + only valid when using UNIX domain sockets (so listen::file). + This way you can override the IP address that users come online with when + they use the socket (default was and still is `127.0.0.1`). +* Add a new guide [Running Tor hidden service with UnrealIRCd](https://www.unrealircd.org/docs/Running_Tor_hidden_service_with_UnrealIRCd) + which uses the new listen::spoof-ip and optionally requires a services account. ### Changes: * The RPC modules are enabled by default now. This so remote RPC works diff --git a/include/struct.h b/include/struct.h index 750059125..de3f5de6a 100644 --- a/include/struct.h +++ b/include/struct.h @@ -1850,6 +1850,7 @@ struct ConfigItem_listen { int options; /**< e.g. LISTENER_BOUND if active */ int clients; /**< Clients connected to this socket / listener */ int fd; /**< File descriptor (if open), or -1 (if not open yet) */ + char *spoof_ip; /**< listen::spoof-ip (only for listen::file, if you want to override 127.0.0.1) */ SSL_CTX *ssl_ctx; /**< SSL/TLS context */ TLSOptions *tls_options; /**< SSL/TLS options */ WebServer *webserver; /**< For the webserver module */ diff --git a/src/conf.c b/src/conf.c index 8cc2ccf14..72c206fb2 100644 --- a/src/conf.c +++ b/src/conf.c @@ -4969,7 +4969,10 @@ void conf_listen_configure(const char *ip, int port, SocketType socket_type, int /* Yeah, we actually do something with this one.. */ if (cep->value) listen->mode = strtol(cep->value, NULL, 8); /* octal */ - } else if (!strcmp(cep->name, "ip")) + } + else if (!strcmp(cep->name, "spoof-ip")) + safe_strdup(listen->spoof_ip, cep->value); + else if (!strcmp(cep->name, "ip")) ; else if (!strcmp(cep->name, "port")) ; @@ -5009,6 +5012,7 @@ int _conf_listen(ConfigFile *conf, ConfigEntry *ce) ConfigEntry *tlsconfig = NULL; char *file = NULL; char *ip = NULL; + char *spoof_ip = NULL; int start=0, end=0, port; int listener_flags =0; Hook *h; @@ -5028,6 +5032,10 @@ int _conf_listen(ConfigFile *conf, ConfigEntry *ce) { ip = cep->value; } else + if (!strcmp(cep->name, "spoof-ip")) + { + spoof_ip = cep->value; + } else if (!strcmp(cep->name, "port")) { port_range(cep->value, &start, &end); @@ -5092,7 +5100,7 @@ int _test_listen(ConfigFile *conf, ConfigEntry *ce) ConfigEntry *cep; ConfigEntry *cepp; int errors = 0; - char has_file = 0, has_ip = 0, has_port = 0, has_options = 0, port_6667 = 0; + char has_file = 0, has_ip = 0, has_port = 0, has_options = 0, port_6667 = 0, has_spoof_ip = 0; char *file = NULL; char *ip = NULL; Hook *h; @@ -5213,6 +5221,16 @@ int _test_listen(ConfigFile *conf, ConfigEntry *ce) has_file = 1; file = cep->value; } else + if (!strcmp(cep->name, "spoof-ip")) + { + has_spoof_ip = 1; + if (!is_valid_ip(cep->value)) + { + config_error("%s:%i: listen::spoof-ip is not a valid IP address (%s)", + cep->file->filename, cep->line_number, cep->value); + errors++; + } + } else if (!strcmp(cep->name, "mode")) { int mode = strtol(cep->value, NULL, 8); @@ -5325,6 +5343,13 @@ int _test_listen(ConfigFile *conf, ConfigEntry *ce) } } + if (has_spoof_ip && !has_file) + { + config_error("%s:%d: listen::spoof-ip is only valid when listen::file is used (UNIX domain sockets)", + ce->file->filename, ce->line_number); + errors++; + } + if (port_6667) safe_strdup(port_6667_ip, ip); diff --git a/src/socket.c b/src/socket.c index 4a508eae0..d4ae4aede 100644 --- a/src/socket.c +++ b/src/socket.c @@ -831,7 +831,7 @@ Client *add_connection(ConfigItem_listen *listener, int fd) client->local->listener->clients++; if (listener->socket_type == SOCKET_TYPE_UNIX) - ip = "127.0.0.1"; + ip = listener->spoof_ip ? listener->spoof_ip : "127.0.0.1"; else ip = getpeerip(client, fd, &port);