AmendHub

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 4 months 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",