Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security] Login timeout after failed attempt, ban after number of failed attempts #640

Closed
FiftyTifty opened this issue Nov 7, 2019 · 24 comments
Assignees

Comments

@FiftyTifty
Copy link

Relevant Reddit thread: https://www.reddit.com/r/MeshCentral/comments/drvyua/login_timeout_and_ip_ban_after_number_of_failed/

Currently, MeshCentral has 2FA support for security, but not several other countermeasures that greatly increase security. Those are:

  1. Login timeout - After an IP has failed to login, there should be a cooldown on either that IP being able to make another login attempt, and/or a cooldown on the account being able to accept another login attempt.

  2. Ban after failed login attempts - If an IP continues to try logging in, and repeatedly fails, the IP should be given a ban for a period of adjustable length, from temporary (e.g, 10 minutes/1 day/1 week), to permanent.

  3. 2FA Timeout - If an IP succeeds at logging in, but repeatedly fails to input the proper 2FA, have a cooldown before the IP can attempt another login, and/or the account can accept login attempts.

  4. Ban after failed 2FA login attempts - If an IP repeatedly succeeds at inputting the username and password, but also repeatedly failing 2FA, ban the IP with an adjustable length (same as suggestion 2).

  5. Generate key for successful login for computer, disable logins from other IPs - A form of 3FA, easily doable with SSH on Ubuntu, is to make it so that after all necessary users have logged into an account from their computer, pair the account (public key) with the private keys and toggle off creating new keys.

Alone, suggestion 5 would be ripe for abuse by malicious actors, but in combination with the previous 4, the server is excessively hardened (in a good way). Coupled with DDOS countermeasures, the internet-accessible server would be as secure as can be, without any usability nightmares.

@PathfinderNetworks
Copy link

At the very least I think options 2 and 4 are necessities. Also, I'd like to see an alerting system in place that will not only log the failed login attempts but will also shoot me an email with the relevant information for every failed attempt (the relevant information being the account name that was used, IP address of the attacker, date, time, etc).
I already have geolocation IP blocking in use and enabled on my firewall (I block pretty much the entire world apart from Western Europe and the US). But I also do permanent IP bans at the firewall level when I see repeated attacks coming from a certain IP address (or subnet). I want to be able to do the same with attacks against my MeshCentral server (hence why I need a log showing the IP address date and time of the attacks).

@MailYouLater
Copy link
Contributor

Also, in the case where someone enters the correct username and password, but incorrect 2FA key, a notification should be shown to the user when they do successfully log in, as this indicates that their account details have been compromised, and they should change their password.

@Ylianst Ylianst self-assigned this Nov 8, 2019
@Ylianst
Copy link
Owner

Ylianst commented Nov 8, 2019

Agreed, I need to build this in. For 5, maybe I could ask for a client side TLS certificate. I like the idea of having a connection authentication of some sort so that you don't even get to see the login page unless you do pre-authentication.

@Ylianst
Copy link
Owner

Ylianst commented Nov 18, 2019

This is not what was asked in this issue, but related so I will mention it here. I just published MeshCentral v0.4.4-j with failed login attempts now logged and a notification when it happens. I wanted to get this done before working on the IP cool down/banning feature. Feedback on this appreciated.

MC2-FailedAuthNotify

@MailYouLater
Copy link
Contributor

I'm not sure 'normal' failed login attempts should be notified about (unless there have been enough to indicate someone's actively trying to guess your password), but I suppose it doesn't matter too much, as long as the much more severe case where the correct username & password were used with incorrect 2FA key is counted and notified about separately, as when this happens, it's imperative that the user change their password ASAP (assuming it wasn't them accidentally mistyping their 2FA key).

@FiftyTifty
Copy link
Author

The only thing I'd suggest, is making it a separate, persistent notification with a different colour. So you'd get the normal notifications in yellow, but a persistent notification in red that doesn't go away unless you click X and confirm closing it with a prompt.

@Ylianst
Copy link
Owner

Ylianst commented Nov 19, 2019

@MailYouLater I see you point about notifying only if the second factor fails, not just normal user/pass fail. I can fix it to only count and notify the second factor fails. Of course, all login failed attempts will be logged.

@Ylianst
Copy link
Owner

Ylianst commented Nov 19, 2019

Published MeshCentral v0.4.4-m with a first form of bad login throttling. You can now specify a time (in minutes) and a max count of bad login attempts before the IP is blocked. The IP address will be blocked until the count goes back down to acceptable levels. By default, I set the values to be 10 bad logins in 10 minutes if you don't configure anything. Feedback appreciated.

MC2-StopBadAuth

@FiftyTifty
Copy link
Author

Having the option to choose the cooldown period would be great, as well as a toggle so that the cooldown is never used, with the IP being permanently banned.

@Ylianst
Copy link
Owner

Ylianst commented Nov 19, 2019

Right now, the "cooldown" is whatever time it takes to get back under the 10 bad in 10 minutes (or whatever values you select). I create a event on each bad login and remove it after 10 minutes. If 10 events are in the list, any login is blocked. So, you can next login when the oldest of the event drops off the list. Hope that makes sense. I can add an option that is the list reaches 10, I "permanently" block.

Since this event list is kept in memory (not the database). The "permanent block" would be until the server is restarted / updated. Feedback on this much appreciated.

@MailYouLater
Copy link
Contributor

MailYouLater commented Nov 19, 2019

So, just to be sure I understand how this works: If you were to set it to 3 bad login attempts in 30 minutes, then if someone failed to log in 3 times in 1 minute, then that IP address will be 'banned' for the next 30 minutes, but if they fail to log in 1 time, then 29 minutes later fail to log in 2 more times, that IP will be banned for 1 minute, then they can try to log in one time before being banned again for the next 29 minutes.

This is a bit of an unusual banning system, but conceptually, I kind of like it, it's more like a form of 'rate-limiting'.

Note: I'm not (yet) one of the people who's actively waiting for this feature (and may be actively battling these kind of attacks), so the people who are may have better feedback than me, but based purely on your descriptions above, my feedback is this:

  • The 'bad logins' should be removed from the list if the person successfully logs in to the same account they were failing to log in to.
    i.e. If it's set up to 3 fails in 5 minutes, and I fail twice, then log in successfully, then accidentally close my browser, when I immediate try to log in again I should be able to fail 2 more times without being forced to wait (maybe I have a bad memory, but know it's one of these three passwords), but only if the account I successfully logged into is the same as the account I was failing to log in to. We don't want to allow people to log into their own account to completely reset the rate limiting, then log back out, try a few more passwords they think their boss might have used, log in and out again, try a few more... ad nauseam.
  • It should be possible to configure the temporary ban/rate limit you've described, and also configure a permanent ban for repeat offenders.
    Not allowing 10 bad logins in 10 minutes is good, but if that's the only ban, then people could keep trying at an average rate of 1 bad login per minute indefinitely. It should be possible to permanently ban someone who's failed (for instance) 500 times in one day, as the likelihood that that's someone that you want logging into your server is unrealistically low.
  • It should be possible to set up some kind of ban persistence to make 'permanent' blocks truly permanent if desired, even if you have to manually enable ban persistence as a separate setting from long-lasting IP blocking.
    I bet there are a number of people who don't want to give someone they've already classified as a 'known attacker' a second chance to get through every time their server needs a restart or upgrade.
    This would likely mean saving the 'permanent' ban list to the neDB/MongoDB database.

@Ylianst
Copy link
Owner

Ylianst commented Nov 19, 2019

You got it exactly right with your 3 bad login in 30 minutes, it is in fact rate limiting. However, I just published MeshCentral v0.4.4-o with the addition of a cool-off period time (in minutes). When the cool-off is set, when the situation causes a IP address to be blocked, it will block it for the cool-off period and all entries are removed. I guess you can set it to "99999999" and have it block pretty much forever. If you don't set the cool-off time, it just rate limiting like before. Feedback on this appreciated.

MC2-StopBadAuth

@MailYouLater
Copy link
Contributor

I really feel like with whether I'm using the rate-limiting approach or including a cool-off time, there should be a separate 'permanent ban' that has a separate limit so that a random user who attempts to log in a bunch of extra times will be rate-limited or given a cool-off period before they can log in again, but an attacker who is (for instance) trying to brute-force their way in eventually gets completely banned, forever. And I feel like this permanent ban list should be (or should be configurable to be) persistent between server reboots.

@Ylianst
Copy link
Owner

Ylianst commented Nov 21, 2019

First, note that in the settings section of config.json, you can set to allow or block IP's and IP ranges for user login. You would use one of these lines:

    "UserAllowedIP": "127.0.0.1,192.168.1.0/24",
    "UserBlockedIP": "127.0.0.1,::1,192.168.0.100"

Of course, you would have to know what IP address to ban, but this is of course persistent. Before I move to more banning features, I think I will work on a simple version of the 3FA idea. You would need to know an extra string to even get a chance to logging to the server.

@MailYouLater
Copy link
Contributor

That looks like a perfect place for MeshCentral to save the list of permanent bans. Then if for some reason you did want to unban someone who had triggered a permanent ban, you would just edit the config.json to remove them from the list.

@Ylianst
Copy link
Owner

Ylianst commented Nov 22, 2019

Well.. I don't really want to write to config.json, sometimes that file will be shared between multiple MeshCentral servers that are behind a load-balancer, is a static configuration file for Docker, etc. I prefer to consider config.json to be read-only. Server state should be in the database and I can make commands in the "My Server" console to see the list, add/remove, etc.

@Ylianst
Copy link
Owner

Ylianst commented Nov 22, 2019

Just published MeshCentral v0.4.4-r with a basic 3FA system. Just add:

"LoginKey" : "abc"

to the domain section of the config.json. When you will need to access your MeshCentral server using the same as before with ?key=abc added to the end of the URL. You will not see the login screen unless you add the key to the url. This is not intended to provide better security, but I guess it would make it harder to port scan and reduce the attack surface a little.

This said, the implementation is very basic, more could be done to improve this. I do want feedback on work so far to see if this looks ok and testing appreciated.

@FiftyTifty
Copy link
Author

FiftyTifty commented Dec 1, 2019

The latest download available on your site is for version 2.2. Does that incorporate the work you've done so far on this 3FA? If so, I'll give it a bash and report back how it fares.

Would having a login key, that's appended to the URL, actually provide any security? Wonder if programs like HTTrack can find the whole URL including the key.

It can't hurt to have that custom URL on top of using a randomly generated keypair. Each additional layer of security, even if one of them is minor, is always a good thing.

Edit: Right, used the installer to update MeshCentral, then restarted the server. MeshCentral Is functioning just as it was before, with no discernable difference. The config.json is different to the one in your screenshot: https://i.imgur.com/oFgQTuq.png

Typing badlogins into the MeshCentral console causes it to say the command is not recognized: https://i.imgur.com/eByBK0D.png

@Ylianst
Copy link
Owner

Ylianst commented Dec 1, 2019

Hi. A few things here. First, the Windows installer version 2.2 is just the version for the installer. The server version is something like MeshCentral v0.4.5-b. To update MeshCentral, use the Windows installer, run it again and select update server. The installer is not updated often, but the server is updated frequently.

A better way to update the server is to login as administrator in your MeshCentral server, go to the "My Server" tab and click "Check version". You will see the current version and if a new one exists, there is a self update option there, should take 10 to 20 seconds.

For the URL login key, it does not add a lot of security but will stop the casual port scanner from seeing the login page, etc. Tools like HTTrack will get not be able to figure out the login key unless someone links your server from a different web page with the loginkey in the link. As long as you just add a bookmark in your browser to your server with the key, you should be fine.

Also, in the very last version of MeshCentral, I added support for many login keys. So you can now add this to your config.json:

"LoginKey" : [ "abc", "def", "hij" ]

Then, any of these 3 keys are acceptable. Hope it helps.

@MailYouLater
Copy link
Contributor

Also, in the very last version of MeshCentral, I added support for many login keys. So you can now add this to your config.json:

"LoginKey" : [ "abc", "def", "hij" ]

Then, any of these 3 keys are acceptable. Hope it helps.

That's cool. I wasn't really sold on the concept of having to enter an extra 'login key' in the URL, but this way you can give different keys to different people, and then remove one if you want to disable that person's access. Obviously different people should have separate accounts, and you should remove the account (or at least change the password) if you want to remove their access, but this gives a small extra layer of security where you can prevent them from even getting to the login page so they can't even try to get in, e.g. to someone else's account.

@Ylianst
Copy link
Owner

Ylianst commented Dec 2, 2019

Right, not sure how practical this is, but at lease a port 80/443 scanner will not get any data. This is really only good for small private servers.

@Ylianst
Copy link
Owner

Ylianst commented Dec 4, 2019

If it's ok, I am going to close this one since the new MeshCentral versions implement the features requested above. If there are problems or new feature requests or refinements that are more specific, please open a new issue.

@Ylianst Ylianst closed this as completed Dec 4, 2019
@FiftyTifty
Copy link
Author

FiftyTifty commented Dec 9, 2019

Got side-tracked a bunch, but am back to working with my server. I would suggest adding a couple of example config.json files that show the various settings available. Or, if it supports comments, just one master config.json with various settings commented out, with a brief explanation on how each setting functions.

For example, if I wanted to add a rather draconian login timeout, and a 3FA string, this would work, right?

{
"settings": {
"cert": "1.2.345.678",
"_minify": true,
"wanonly": true,
"minify": true,
"MaxInvalidLogins": {
"time": 60,
"count": 3,
"coolofftime": 1440
}
},
"domains": {
"": {
"newaccounts": false,
"LoginKey" : "abc"
}
}
}

Somewhat related, would be a quick tutorial on setting up RDP through MeshCentral Router, with the various 2fa and 3fa settings enabled. Don't see anything in the current .docx manuals that explain any differences in set up, when using these security settings.

@MailYouLater
Copy link
Contributor

Unfortunately, the way the MC reads the config.json file, it doesn't support any comment systems, so @Ylianst currently uses a pseudo-comment system where he puts a bunch of comments in the config.json file with underscores before the name of settings, but this isn't really ideal, especially in the "domains" section, where the presence of "_customer1" in the sample config causes the server to allow someone to get in and start using your server via the "_customer1" portal unless you deleted those lines when you edited the config file to meet your needs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants