P
Pvt Ryan
Background:
Due to the large number of bots attempting to ssh to my server, I
implemented portknocking (as the logs were just filled with crap).
So to access port 2222 for ssh I would first need to connect on port
3333 which opens port 2222 for 60secs.
(obv I just made those ports up)
I wanted to continue to use putty under windows to connect to my
server. However its a bit of hassle to connect manually to 1 port 1st
and then do the real connection.
The devs at putty have said they won't implement port knocking which
is fine, so i decided to build putty from source and add the port
knocking to my copy.
Problem:
I implemented it and it works, sort of.
Unfortunately (under windows) the 1st attempted connection (the knock)
times out (within 30secs) and in doing so kills my active putty
window.
Under linux due to the -Werror flag my build fails with the following:
--------------------------------------------------------------------
cc1: warnings being treated as errors
../ssh.c:2829: warning: function definition has qualified void return
type
../ssh.c: In function ‘knock’:
../ssh.c:2845: warning: statement with no effect
make: *** [ssh.o] Error 1
----------------------------------------------------------------------
Now if i edit the makefile and remove the -Werror flag and then run
make again it will build fine.
It times out after about 5min.
Can anyone help me sort this?
portknock.patch
----------------------
Index: config.c
===================================================================
--- config.c (revision 8122)
+++ config.c (working copy)
@@ -1989,6 +1989,35 @@
I(offsetof(Config,ssh2_des_cbc)));
}
+ /* The Connection/SSH/PortKnock panel. Allows the setting up
of
+ * port knocking.
+ */
+
+ if (!midsession) {
+ ctrl_settitle(b, "Connection/SSH/PortKnock",
+ "Options controlling port knocking");
+
+ s = ctrl_getset(b, "Connection/SSH/PortKnock", "main",
+ "Port Knocking options");
+
+ ctrl_checkbox(s, "Enable Port Knocking",
+ 'e', HELPCTX(ssh_auth_ki),
+ dlg_stdcheckbox_handler,
+ I(offsetof(Config,pk_enable)));
+
+ ctrl_editbox(s, "1st Port to knock on:", 'p', 20,
+ HELPCTX(ssh_kex_repeat),
+ dlg_stdeditbox_handler,
+ I(offsetof(Config,pk_port1)),
+ I(-1));
+
+ ctrl_editbox(s, "2nd Port to knock on:", 'n', 20,
+ HELPCTX(ssh_kex_repeat),
+ dlg_stdeditbox_handler,
+ I(offsetof(Config,pk_port2)),
+ I(-1));
+ }
+
/*
* The Connection/SSH/Kex panel. (Owing to repeat key
* exchange, this is all meaningful in mid-session _if_
Index: putty.h
===================================================================
--- putty.h (revision 8122)
+++ putty.h (working copy)
@@ -464,6 +464,10 @@
int ssh_no_shell; /* avoid running a shell */
char ssh_nc_host[512]; /* host to connect to in `nc' mode
*/
int ssh_nc_port; /* port to connect to in `nc' mode */
+ /* Port Knocking */
+ int pk_enable;
+ int pk_port1;
+ int pk_port2;
/* Telnet options */
char termtype[32];
char termspeed[32];
Index: ssh.c
===================================================================
--- ssh.c (revision 8122)
+++ ssh.c (working copy)
@@ -2824,6 +2824,40 @@
* Also places the canonical host name into `realhost'. It must be
* freed by the caller.
*/
+
+static const void knock(Ssh ssh, char *host, int port, char
**realhost)
+{
+ static const struct plug_function_table fn_table = {
+ ssh_log,
+ ssh_closing,
+ ssh_receive,
+ ssh_sent,
+ NULL
+ };
+
+ SockAddr addr;
+ const char *err;
+
+ /*
+ * Try to find host.
+ */
+ ssh->cfg.addressfamily == ADDRTYPE_IPV4 ? " (IPv4)" :
+ (ssh->cfg.addressfamily == ADDRTYPE_IPV6 ? " (IPv6)" : "");
+ addr = name_lookup(host, port, realhost, &ssh->cfg,
+ ssh->cfg.addressfamily);
+ if ((err = sk_addr_error(addr)) != NULL) {
+ sk_addr_free(addr);
+ }
+
+ /*
+ * Open socket.
+ */
+ ssh->fn = &fn_table;
+ ssh->s = new_connection(addr, *realhost, port,
+ 0, 1, 1, 0, (Plug) ssh, &ssh->cfg);
+ ssh->s = NULL;
+}
+
static const char *connect_to_host(Ssh ssh, char *host, int port,
char **realhost, int nodelay, int keepalive)
{
@@ -8864,6 +8898,24 @@
ssh->max_data_size = parse_blocksize(ssh->cfg.ssh_rekey_data);
ssh->kex_in_progress = FALSE;
+ if (ssh->cfg.pk_enable == TRUE) { /* If port knocking is enabled */
+ if (ssh->cfg.pk_port1 > 0) { /* We knock on this port 1st */
+ /* Attempt to connect to port and immeditatly close connection
+ * if successful and if not (which is more likely) continue.
+ */
+ // Kills active window instead of dropping silently
+
+ knock(ssh, host, ssh->cfg.pk_port1, realhost);
+ if (ssh->cfg.pk_port2 > 0) { /* We then knock on this port if need
be */
+ /* Attempt to connect to port and immeditatly close connection
+ * if successful and if not (which is more likely) continue.
+ */
+ knock(ssh, host, ssh->cfg.pk_port2, realhost);
+ }
+ }
+ /* If both ports are 0 we do nothing */
+ }
+
p = connect_to_host(ssh, host, port, realhost, nodelay,
keepalive);
if (p != NULL)
return p;
Due to the large number of bots attempting to ssh to my server, I
implemented portknocking (as the logs were just filled with crap).
So to access port 2222 for ssh I would first need to connect on port
3333 which opens port 2222 for 60secs.
(obv I just made those ports up)
I wanted to continue to use putty under windows to connect to my
server. However its a bit of hassle to connect manually to 1 port 1st
and then do the real connection.
The devs at putty have said they won't implement port knocking which
is fine, so i decided to build putty from source and add the port
knocking to my copy.
Problem:
I implemented it and it works, sort of.
Unfortunately (under windows) the 1st attempted connection (the knock)
times out (within 30secs) and in doing so kills my active putty
window.
Under linux due to the -Werror flag my build fails with the following:
--------------------------------------------------------------------
cc1: warnings being treated as errors
../ssh.c:2829: warning: function definition has qualified void return
type
../ssh.c: In function ‘knock’:
../ssh.c:2845: warning: statement with no effect
make: *** [ssh.o] Error 1
----------------------------------------------------------------------
Now if i edit the makefile and remove the -Werror flag and then run
make again it will build fine.
It times out after about 5min.
Can anyone help me sort this?
portknock.patch
----------------------
Index: config.c
===================================================================
--- config.c (revision 8122)
+++ config.c (working copy)
@@ -1989,6 +1989,35 @@
I(offsetof(Config,ssh2_des_cbc)));
}
+ /* The Connection/SSH/PortKnock panel. Allows the setting up
of
+ * port knocking.
+ */
+
+ if (!midsession) {
+ ctrl_settitle(b, "Connection/SSH/PortKnock",
+ "Options controlling port knocking");
+
+ s = ctrl_getset(b, "Connection/SSH/PortKnock", "main",
+ "Port Knocking options");
+
+ ctrl_checkbox(s, "Enable Port Knocking",
+ 'e', HELPCTX(ssh_auth_ki),
+ dlg_stdcheckbox_handler,
+ I(offsetof(Config,pk_enable)));
+
+ ctrl_editbox(s, "1st Port to knock on:", 'p', 20,
+ HELPCTX(ssh_kex_repeat),
+ dlg_stdeditbox_handler,
+ I(offsetof(Config,pk_port1)),
+ I(-1));
+
+ ctrl_editbox(s, "2nd Port to knock on:", 'n', 20,
+ HELPCTX(ssh_kex_repeat),
+ dlg_stdeditbox_handler,
+ I(offsetof(Config,pk_port2)),
+ I(-1));
+ }
+
/*
* The Connection/SSH/Kex panel. (Owing to repeat key
* exchange, this is all meaningful in mid-session _if_
Index: putty.h
===================================================================
--- putty.h (revision 8122)
+++ putty.h (working copy)
@@ -464,6 +464,10 @@
int ssh_no_shell; /* avoid running a shell */
char ssh_nc_host[512]; /* host to connect to in `nc' mode
*/
int ssh_nc_port; /* port to connect to in `nc' mode */
+ /* Port Knocking */
+ int pk_enable;
+ int pk_port1;
+ int pk_port2;
/* Telnet options */
char termtype[32];
char termspeed[32];
Index: ssh.c
===================================================================
--- ssh.c (revision 8122)
+++ ssh.c (working copy)
@@ -2824,6 +2824,40 @@
* Also places the canonical host name into `realhost'. It must be
* freed by the caller.
*/
+
+static const void knock(Ssh ssh, char *host, int port, char
**realhost)
+{
+ static const struct plug_function_table fn_table = {
+ ssh_log,
+ ssh_closing,
+ ssh_receive,
+ ssh_sent,
+ NULL
+ };
+
+ SockAddr addr;
+ const char *err;
+
+ /*
+ * Try to find host.
+ */
+ ssh->cfg.addressfamily == ADDRTYPE_IPV4 ? " (IPv4)" :
+ (ssh->cfg.addressfamily == ADDRTYPE_IPV6 ? " (IPv6)" : "");
+ addr = name_lookup(host, port, realhost, &ssh->cfg,
+ ssh->cfg.addressfamily);
+ if ((err = sk_addr_error(addr)) != NULL) {
+ sk_addr_free(addr);
+ }
+
+ /*
+ * Open socket.
+ */
+ ssh->fn = &fn_table;
+ ssh->s = new_connection(addr, *realhost, port,
+ 0, 1, 1, 0, (Plug) ssh, &ssh->cfg);
+ ssh->s = NULL;
+}
+
static const char *connect_to_host(Ssh ssh, char *host, int port,
char **realhost, int nodelay, int keepalive)
{
@@ -8864,6 +8898,24 @@
ssh->max_data_size = parse_blocksize(ssh->cfg.ssh_rekey_data);
ssh->kex_in_progress = FALSE;
+ if (ssh->cfg.pk_enable == TRUE) { /* If port knocking is enabled */
+ if (ssh->cfg.pk_port1 > 0) { /* We knock on this port 1st */
+ /* Attempt to connect to port and immeditatly close connection
+ * if successful and if not (which is more likely) continue.
+ */
+ // Kills active window instead of dropping silently
+
+ knock(ssh, host, ssh->cfg.pk_port1, realhost);
+ if (ssh->cfg.pk_port2 > 0) { /* We then knock on this port if need
be */
+ /* Attempt to connect to port and immeditatly close connection
+ * if successful and if not (which is more likely) continue.
+ */
+ knock(ssh, host, ssh->cfg.pk_port2, realhost);
+ }
+ }
+ /* If both ports are 0 we do nothing */
+ }
+
p = connect_to_host(ssh, host, port, realhost, nodelay,
keepalive);
if (p != NULL)
return p;