jcs
/subtext
/amendments
/204
telnet: When banning an IP, optionally send it via UDP to trusted proxy
If the new trusted_proxy_udp_port config option is set, send a UDP
packet containing the IP to the trusted_proxy_ip host so it can ban
it more aggressively.
jcs made amendment 204 over 2 years ago
--- db.c Wed Jul 13 10:14:30 2022
+++ db.c Wed Jul 13 17:45:43 2022
@@ -45,6 +45,9 @@ struct struct_field config_fields[] = {
{ "Telnet Trusted Proxy IP", CONFIG_TYPE_IP,
offsetof(struct config, trusted_proxy_ip),
0, 1 },
+ { "Telnet Trusted Proxy UDP Port", CONFIG_TYPE_SHORT,
+ offsetof(struct config, trusted_proxy_udp_port),
+ 0, 65535 },
{ "Modem Port", CONFIG_TYPE_SHORT,
offsetof(struct config, modem_port),
0, 2 },
@@ -367,6 +370,18 @@ db_migrate(struct db *tdb, short is_new)
bile_read(tdb->bile, DB_CONFIG_RTYPE, 1, (char *)&new_config,
sizeof(new_config));
new_config.modem_speed = 19200;
+
+ bile_write(tdb->bile, DB_CONFIG_RTYPE, 1, &new_config,
+ sizeof(new_config));
+ break;
+ }
+ case 7: {
+ /* 7->8, added trusted_proxy_udp_port */
+ struct config new_config = { 0 };
+
+ bile_read(tdb->bile, DB_CONFIG_RTYPE, 1, (char *)&new_config,
+ sizeof(new_config));
+ new_config.trusted_proxy_udp_port = 0;
bile_write(tdb->bile, DB_CONFIG_RTYPE, 1, &new_config,
sizeof(new_config));
--- db.h Wed Jul 13 09:25:38 2022
+++ db.h Wed Jul 13 17:44:37 2022
@@ -23,7 +23,7 @@
#define DB_TYPE 'STDB'
-#define DB_CUR_VERS 7
+#define DB_CUR_VERS 8
#define DB_TRUE 0x100
#define DB_FALSE 0x000
@@ -77,6 +77,7 @@ struct config {
short blanker_runtime_seconds;
unsigned long trusted_proxy_ip;
unsigned long modem_speed;
+ unsigned short trusted_proxy_udp_port;
};
extern struct struct_field config_fields[];
--- telnet.c Mon Jul 11 13:32:06 2022
+++ telnet.c Thu Jul 14 09:41:45 2022
@@ -117,6 +117,12 @@ static struct telnet_node *telnet_listener_node = NULL
static TCPiopb telnet_exit_pb;
static TCPStatusPB telnet_status_pb;
static bool did_initial_log = false;
+static UDPiopb udp_ban_pb;
+static StreamPtr udp_ban_stream;
+static char *udp_ban_rcv_buf;
+#define UDP_BAN_RCV_BUF_SIZE 2048
+static wdsEntry udp_ban_wds[2];
+static char udp_ban_send_buf[16];
#define MAX_BANNED_IPS 20
#define IP_BAN_SECONDS (60 * 30)
@@ -152,7 +158,7 @@ struct node_funcs telnet_node_funcs = {
void
telnet_init(void)
{
- short n;
+ short n, error;
if (!db->config.telnet_port)
return;
@@ -170,6 +176,16 @@ telnet_init(void)
if (n == 0)
telnet_listen_on_node(telnet_nodes[n]);
}
+
+ if (db->config.trusted_proxy_ip != 0 &&
+ db->config.trusted_proxy_udp_port != 0) {
+ udp_ban_rcv_buf = xmalloc(UDP_BAN_RCV_BUF_SIZE);
+ error = _UDPCreate(&udp_ban_pb, &udp_ban_stream,
+ (Ptr)udp_ban_rcv_buf, UDP_BAN_RCV_BUF_SIZE, NULL, NULL,
+ NULL, false);
+ if (error)
+ panic("UDPCreate failed: %d", error);
+ }
}
void
@@ -191,6 +207,10 @@ telnet_atexit(void)
}
telnet_listener_node = NULL;
+
+ if (db->config.trusted_proxy_ip != 0 &&
+ db->config.trusted_proxy_udp_port != 0)
+ _UDPRelease(&udp_ban_pb, udp_ban_stream, NULL, NULL, false);
}
void
@@ -292,7 +312,6 @@ telnet_idle(void)
node->ip_s);
_TCPRelease(&node->listen_pb, node->stream, nil,
nil, false);
-
node->state = TELNET_PB_STATE_UNUSED;
goto next_node;
}
@@ -801,7 +820,9 @@ void
telnet_close(struct session *session)
{
struct telnet_node *node = (struct telnet_node *)session->cookie;
+ size_t len;
short error, n;
+ unsigned char *tmp;
if (node->from_trusted_proxy)
session->ban_node_source = false;
@@ -821,6 +842,24 @@ telnet_close(struct session *session)
banned_ips[n].time = Time;
break;
}
+ }
+
+ if (db->config.trusted_proxy_ip != 0 &&
+ db->config.trusted_proxy_udp_port != 0) {
+ tmp = (unsigned char *)&node->ip;
+ len = snprintf(udp_ban_send_buf, sizeof(udp_ban_send_buf),
+ "%d.%d.%d.%d", tmp[0], tmp[1], tmp[2], tmp[3]);
+ udp_ban_wds[0].ptr = (Ptr)&udp_ban_send_buf;
+ udp_ban_wds[0].length = len;
+ udp_ban_wds[1].ptr = 0;
+ udp_ban_wds[1].length = 0;
+
+ error = _UDPSend(&udp_ban_pb, udp_ban_stream, udp_ban_wds,
+ db->config.trusted_proxy_ip,
+ db->config.trusted_proxy_udp_port, NULL, NULL, false);
+ if (error)
+ session_log(session, "Failed sending IP ban UDP packet: %d",
+ error);
}
} else {
session_log(session, "Closing telnet connection from %s",