[Patch] Restricting access to certain ip numbers.

Hans Harder hans at atbas.org
Sat Oct 4 20:44:22 WST 2014


Perhaps not something to have default in dropbear, put perhaps of interest
for someone...

In order to restrict  access from certain ip addresses only, you can, with
this patch, start a dropbear with option -S
This will only allow password logins if a corresponding file
/etc/dropbear/ip_<ipnumber>_any.allow exists.

It will also check for /etc/dropbear/ip_<ipnumber>_<username>.allow for
granting access to specific usernames only

If you start dropbear with -S -S  it will also use this restriction for
pubkey validation

Example:
# blocking password and pubkey from unknown locations, using a valid pubkey
root at core ~# ./dropbear -S -S  -F  -p 2022
[24472] Oct 04 12:30:21 Not backgrounding
[24473] Oct 04 12:30:40 Child connection from ::ffff:192.168.1.10:49799
[24473] Oct 04 12:30:40 Exit before auth (user 'root', 0 fails): Remote
address ::ffff:192.168.1.10:49799 is not allowed to connect with public key
or password

# blocking password from unknown locations, using a valid pubkey
root at core ~# ./dropbear -S   -F  -p 2022
[24486] Oct 04 12:30:55 Not backgrounding
[24487] Oct 04 12:31:10 Child connection from ::ffff:192.168.1.10:49801
[24487] Oct 04 12:31:11 Pubkey auth succeeded for 'root' with key md5
14:07:9a:1d:d9:64:45:db:88:d8:78:62:45:1e:88:21 from ::ffff:
192.168.1.10:49801

# blocking password from unknown locations, using a valid password
root at core ~# ./dropbear -S   -F  -p 2022
[24551] Oct 04 12:31:25 Not backgrounding
[24552] Oct 04 12:32:06 Child connection from ::ffff:192.168.1.10:49802
[24552] Oct 04 12:32:09 IP access denied : file
/etc/dropbear/ip_192.168.1.10_root.allow not found
[24552] Oct 04 12:32:09 IP access denied : file
/etc/dropbear/ip_192.168.1.10_any.allow not found
[24552] Oct 04 12:32:09 Exit before auth (user 'root', 0 fails): Remote
address ::ffff:192.168.1.10:49802 is not allowed to connect with password

# grant  connections for root from 192.168.1.10, using a valid publickey
root at core ~# touch /etc/dropbear/ip_192.168.1.10_root.allow
root at core ~# ./dropbear -S -S  -F  -p 2022
[24578] Oct 04 12:33:02 Not backgrounding
[24579] Oct 04 12:33:20 Child connection from ::ffff:192.168.1.10:49803
[24579] Oct 04 12:33:20 IP access allowed : file
/etc/dropbear/ip_192.168.1.10_root.allow found
[24579] Oct 04 12:33:20 Pubkey auth succeeded for 'root' with key md5
14:07:9a:1d:d9:64:45:db:88:d8:78:62:45:1e:88:21 from ::ffff:
192.168.1.10:49803


Have fun with it...

Hans
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ucc.gu.uwa.edu.au/pipermail/dropbear/attachments/20141004/136f0666/attachment.htm 
-------------- next part --------------
--- ../dropbear-2014.65/options.h	2014-09-11 02:37:28.000000000 -0600
+++ options.h	2014-10-04 01:28:55.000000000 -0600
@@ -20,6 +20,10 @@
 #endif
 
 /* Default hostkey paths - these can be specified on the command line */
+#ifndef CONFIG_DIRECTORY
+#define CONFIG_DIRECTORY "/etc/dropbear"
+#endif
+/* Default hostkey paths - these can be specified on the command line */
 #ifndef DSS_PRIV_FILENAME
 #define DSS_PRIV_FILENAME "/etc/dropbear/dropbear_dss_host_key"
 #endif
--- ../dropbear-2014.65/runopts.h	2014-08-08 07:40:47.000000000 -0600
+++ runopts.h	2014-10-04 01:25:22.000000000 -0600
@@ -87,6 +87,7 @@ typedef struct svr_runopts {
 
 	int norootlogin;
 
+	int restrictlogins;
 	int noauthpass;
 	int norootpass;
 	int allowblankpass;
--- ../dropbear-2014.65/svr-runopts.c	2014-08-08 07:40:47.000000000 -0600
+++ svr-runopts.c	2014-10-04 02:58:05.000000000 -0600
@@ -68,6 +68,7 @@ static void printhelp(const char * progn
 					"-m		Don't display the motd on login\n"
 #endif
 					"-w		Disallow root logins\n"
+					"-S		Enable logins from restricted addresses\n"
 #if defined(ENABLE_SVR_PASSWORD_AUTH) || defined(ENABLE_SVR_PAM_AUTH)
 					"-s		Disable password logins\n"
 					"-g		Disable password logins for root\n"
@@ -127,6 +128,7 @@ void svr_getopts(int argc, char ** argv)
 	svr_opts.forkbg = 1;
 	svr_opts.norootlogin = 0;
 	svr_opts.noauthpass = 0;
+	svr_opts.restrictlogins = 0;
 	svr_opts.norootpass = 0;
 	svr_opts.allowblankpass = 0;
 	svr_opts.inetdmode = 0;
@@ -244,6 +246,9 @@ void svr_getopts(int argc, char ** argv)
 				case 'I':
 					next = &idle_timeout_arg;
 					break;
+				case 'S':
+					svr_opts.restrictlogins++;
+					break;
 #if defined(ENABLE_SVR_PASSWORD_AUTH) || defined(ENABLE_SVR_PAM_AUTH)
 				case 's':
 					svr_opts.noauthpass = 1;
--- ../dropbear-2014.65/svr-auth.c	2014-08-08 07:40:47.000000000 -0600
+++ svr-auth.c	2014-10-04 05:35:21.000000000 -0600
@@ -79,6 +79,46 @@ static void authclear() {
 	
 }
 
+/* check if a file  ip_<ipnumber>_<user>.allow or ip_<ipnumber>.allow is found
+ * which determines if access is allowed or not. */
+static int restrictlogin_valid(char *usernm, int log)
+{
+	char address[65], *ptr, fn[256];
+	
+	/* get remote ip:port address IPv4 or IPv6 */
+	if (strncmp(svr_ses.addrstring,"::ffff:",7)==0) {
+		strlcpy(address,&svr_ses.addrstring[7],sizeof(address));
+	} else {
+		strlcpy(address,svr_ses.addrstring,sizeof(address));
+	}
+	ptr=strrchr(address,':');
+	if (ptr!=0) {
+		/* remove the port part, leaving the ip only in the address */
+		*ptr='\0'; 
+		/* change all remaining : characters into . characters (IPv6) */
+		while ( (ptr=strchr(address,':')) !=0 ) {
+			*ptr='.';
+		}
+        	/* test if user from ip is allowed */
+		snprintf(fn,sizeof(fn),"%s/ip_%s_%s.allow",CONFIG_DIRECTORY,address,usernm);
+		if (access(fn,F_OK)==0) {
+			dropbear_log(LOG_INFO, "IP access allowed : file %s found",fn);
+			return(1);
+		} else if (log) {
+			dropbear_log(LOG_INFO, "IP access denied : file %s not found",fn);
+		}
+        	/* test if any user from ip is allowed */
+		snprintf(fn,sizeof(fn),"%s/ip_%s_any.allow",CONFIG_DIRECTORY,address);
+		if (access(fn,F_OK)==0) {
+			dropbear_log(LOG_INFO, "IP access allowed : file %s found",fn);
+			return(1);
+		} else if (log) {
+			dropbear_log(LOG_INFO, "IP access denied : file %s not found",fn);
+		}
+	}
+	return(0);
+}
+
 /* Send a banner message if specified to the client. The client might
  * ignore this, but possibly serves as a legal "no trespassing" sign */
 void send_msg_userauth_banner(buffer *banner) {
@@ -148,6 +188,10 @@ void recv_msg_userauth_request() {
 			strncmp(methodname, AUTH_METHOD_NONE,
 				AUTH_METHOD_NONE_LEN) == 0) {
 		TRACE(("recv_msg_userauth_request: 'none' request"))
+		if (svr_opts.allowblankpass && svr_opts.restrictlogins!=0 && restrictlogin_valid(username,1)==0) {
+    		        dropbear_log(LOG_INFO, "IP access denied for blank password" );
+			valid_user = 0;
+		}
 		if (valid_user
 				&& svr_opts.allowblankpass
 				&& !svr_opts.noauthpass
@@ -176,6 +220,13 @@ void recv_msg_userauth_request() {
 		if (methodlen == AUTH_METHOD_PASSWORD_LEN &&
 				strncmp(methodname, AUTH_METHOD_PASSWORD,
 					AUTH_METHOD_PASSWORD_LEN) == 0) {
+			if (svr_opts.restrictlogins!=0 && restrictlogin_valid(username,1)==0 ) {
+				/* do not allow retries */
+				m_free(username);
+				m_free(servicename);
+				m_free(methodname);
+				dropbear_exit("Remote address %s is not allowed to connect with password",svr_ses.addrstring);
+			}
 			if (valid_user) {
 				svr_auth_password();
 				goto out;
@@ -191,6 +242,13 @@ void recv_msg_userauth_request() {
 		if (methodlen == AUTH_METHOD_PASSWORD_LEN &&
 				strncmp(methodname, AUTH_METHOD_PASSWORD,
 					AUTH_METHOD_PASSWORD_LEN) == 0) {
+			if (valid_user && svr_opts.restrictlogins!=0 && restrictlogin_valid(username,1)==0 ) {
+				/* do not allow retries */
+				m_free(username);
+				m_free(servicename);
+				m_free(methodname);
+				dropbear_exit("Remote address %s is not allowed to connect with pam password",svr_ses.addrstring);
+			}
 			if (valid_user) {
 				svr_auth_pam();
 				goto out;
@@ -204,6 +262,13 @@ void recv_msg_userauth_request() {
 	if (methodlen == AUTH_METHOD_PUBKEY_LEN &&
 			strncmp(methodname, AUTH_METHOD_PUBKEY,
 				AUTH_METHOD_PUBKEY_LEN) == 0) {
+		if (svr_opts.restrictlogins==2 && restrictlogin_valid(username,0)==0) {
+			/* if pubkey is not allowed , so is password not... so break off connection */
+			m_free(username);
+			m_free(servicename);
+			m_free(methodname);
+			dropbear_exit("Remote address %s is not allowed to connect with public key or password",svr_ses.addrstring);
+		}
 		if (valid_user) {
 			svr_auth_pubkey();
 		} else {


More information about the Dropbear mailing list