mail-in-a-box / mailinabox

Mail-in-a-Box helps individuals take back control of their email by defining a one-click, easy-to-deploy SMTP+everything else server: a mail server in a box.
https://mailinabox.email/
Creative Commons Zero v1.0 Universal
13.92k stars 1.43k forks source link

Admin Interface is publicly accessible, some thoughts how to restrict the interface #963

Open h8h opened 8 years ago

h8h commented 8 years ago

Hi,

The admin interface is publicly accessible. That makes it vulnerable for Brute Force Attacks.

Since miab should be easy to use a pre-basic auth or an ip restriction is very inconvenient. Furthermore tunneling the interface via ssh ssh -L4443:localhost:443 miab@miabserver.tld is also a bad idea for windows users.

I would like to provide another idea: certificate based authentification.

Nginx only needs the following three lines to offer an optional certificate based authentification.

ssl_certificate /home/user-data/ssl/ssl_certificate.pem;
ssl_certificate_key /home/user-data/ssl/ssl_private_key.pem;
+ ssl_client_certificate /path/to/ca.crt;
+ ssl_crl /path/to/ca-crl.crt;
+ ssl_verify_client optional; # or `on` if you require client key

The certificate based authentification happens in a very early connection establishing state. Thats why Nginx only sets a variable called $ssl_client_verify. If the variable equals SUCCESS the user has provided a valid certificate.

To keep it simple a user can generate his/her client certificate in the admin interface, download and install it in the browser.

Its possible to pass the Nginx $ssl_client_verify variable to the admin interface and check if the authentification was successful before requiring certificate based auth.

To require certificated based auth only on /admin Nginx needs an if statement:

if($ssl_client_verify != SUCCESS) {
            return 404;
}

That makes it easy to maintain and enable / disable it at any time. Maybe a /tools/reset_cert_auth.sh is necessary if a user loses his certificate.

The certificate basic auth should only prevent arbitrary users accessing the admin interface, not to login a user without a password.

So I think its a very simple option for the admin to restrict the interface and I can provide a PR.

So whats your opinion?

Update Gist - Mini Tutorial

jookk commented 8 years ago

👍

yodax commented 8 years ago

The admin interface is publicly accessible. That makes it vulnerable for Brute Force Attacks.

Systems with firewall's enabled should block repeated failed login attempts.

I use client certificates for my personal sites. I like that I don't have to type a password.

I don't think many people are familiar with it and getting the generated certificate off the box and on the admin's computer might be challenging for some. Dynamic dns using curl would also need the certificate.

JoshData commented 7 years ago

It could be worth making changes so it's easier for people to insert those nginx directives. But I think client certs is way beyond the abilities and needs of most users, so I don't think I want to add something specifically for client certs.

nomandera commented 7 years ago

Giving people more nginx power gets my vote. I suspect we will see some interesting PRs once the hurdles are removed for the average dev.

One other idea for securing the admin interface is to close it using the fw and have the fw open access only on SSH login e.g. ssh login first to auto activate the admin GUI.

bronson commented 7 years ago

How about putting it behind a simple, user-chosen term? During setup, MiaB would ask for a word ("grape"), then put the URLs there:

http://int.u32.net/grape/admin

Heck, I'd probably prefer Owncloud and maybe Roundcube to be similarly obscured.

Anyone who has run ssh on another port has seen that it doesn't take much to deter script kiddies.

wbnns commented 7 years ago

+1 for some kind of feature that would allow for something other than the current /admin/ location that's accessible to the world. Happy to help submit a PR and update the docs, etc. in conjunction with whatever technical route you all decide on.

zatricky commented 7 years ago

@bronson / @wbinns: Re custom path, probably a good idea - but strongly suggest making a separate issue/PR as this is about client certs.

I like the idea of client certs. I also agree it is a good idea rather to plan/implement groundwork to support it in future rather than to build it all in one go.

Personally I think the ultimate would be that there be an option to force the interface to only show certificate-creation tools if the user is not already using a cert.

bronson commented 7 years ago

this is about client certs.

@zatricky if so, it sounds like this issue's title should be updated?

Agree, and I'm happy to open a path customization issue/PR once I don't have so may others in progress. Would be fine if else beats me to it. :)

h8h commented 7 years ago

The owner of this issue like client certs :), but I'm happy to see other, maybe easier ways to restrict the access to /admin a bit more. Thats why the topic doesn't mention the term client certs.

So feel free to provide your obscures solutions :).

Putting the /admin behind a simple, user-chosen term sounds like a good and easy idea. It is not that secure, but its easy to setup and maintain. If you peform a brute-force directory attack and the user chooses a word which is in a directory, i.e. grape its likely that the attacker finds the directory.

JoshData commented 7 years ago

I'm not going to merge anything that creates "security through obscurity."

biermeester commented 7 years ago

I don't get why a lot of people see it as creating security through obscurity. As I see it, it would be increasing security through obscurity. But maybe that's a discussion for another time and place :)

zatricky commented 7 years ago

@bronson my bad

nomandera commented 7 years ago

It is a controversial subject but in my opinion is very much that "security through obscurity" is clearly part of any "security in depth" approach.

"security through obscurity" can only a bad thing when the audience may mistake it for a complete solution but it demonstrably helps reduce the attack surface and absolutely in the real world can reduce noise considerably.

Clearly the audience here will never make the kind of n00b mistake that it is real security but equally that does not make it worthless in itself.

msgerbs commented 7 years ago

I would much rather see client certs than hiding it behind a different directory. I disagree that client certs is beyond the capabilities of an average MIAB user, after all MIAB will pester you on the status about setting up certificate-based SSL auth, which is about as difficult. If it was set up in the web admin panel it could be made as easy as clicking a button which would generate a certificate and provide the private key to the client. Perhaps not the most security-conscious way to do it, but it's better than not supporting it at all. Otherwise, you could provide instructions on generating a certificate and a place to add it in the admin panel. You'd have to have a Python script in the utilities folder to disable certificate authentication for a user in case they lose the key, probably.

MIAB is designed to be secure out of the box, but a password-based admin panel remains a weakness and I think this is a good way to address that.

GaryBrittain commented 7 years ago

I used to run an instance of PrestaShop and the admin panel on there was obscured by a URL directory made up of something like 20 random letters/numbers that was generated during installation. Security through obscurity again, but an idea.

guyzmo commented 7 years ago

my $.02 on the matter:

changing the path to /admin is wrong: it's not changing the attack surface (some scripts are already trying to domain.tld/{random-strings}/admin to bruteforce).

Just out of my mind I can suggest three ways to improve the security of the admin panel access:

  1. the client certificate solution is elegant and could be considered as an opt-in solution, in parallel to the "standard" password scheme
  2. implementing a TOTP 2FA could be another solution, and maybe a better one. (there's already a discussion about it and a workin progress cf #10)
  3. making it possible to create a VPN and have the /admin accessible only from IPs within the VPN could be a good idea.
    • e.g.: tinc is a great, simple, P2P, KISS VPN tool that just works, and has clients on linux/OSX/windows.

If I had to guess @JoshData's views on the topic:

bronson commented 7 years ago

some scripts are trying domain.tld/{random-strings}/admin

Evidence please? I maintain a few gige-connected machines and I've never seen this. I've seen /cucme/admin etc of course, but never random strings. How much traffic / unique guesses-per-second does this take up on your box? How do you filter all that noise out of your logs?

Hiding the admin panel behind a random string -- by definition -- reduces the attack surface. Whether it's worth it is another matter.

My perspective is:

  1. OK if it's optional, but too difficult to require part-time admins to use.
  2. Open for 2.5 years and no forward progress... Not landing any time soon.
  3. Too much additional maintenance work.
guyzmo commented 7 years ago

First, bruteforce can be easily stopped with proper configuration of fail2ban, the same way it's properly protecting SSH (and BTW, having a proper cypher configuration of SSH stops all brute force scripts).

Generally speaking, crawling scripts looking for known paths are designed against a specific exploit. That means that even if a script kiddie crawler accesses the /admin panel, the html it's receiving will abort as it won't know what to exploit there. It might try to bruteforce if it sees a login/passwd, but cf above.

So if MIAB takes enough traction that it becomes interesting for malware writers to create an exploit taking advantage of some yet-to-discover bug in MIAB auth scheme (and the underlying flask stack), then that script will also be designed to find efficiently the admin page. Whether the path is obfuscated or not.

All in all, it's better to have software that does security by design instead of implementing workarounds that just pushes the problem a bit further, but also gives a false sense of security.

The only compromise I'd be ok with, would be to have /admin renamed something like /panel or /miab or something like that… Mostly because I never liked the /admin path ☺.

bronson commented 7 years ago

bruteforce can be easily stopped with proper configuration of fail2ban

Easily? Care to submit a PR?

the script will also be designed to find efficiently the admin page. Whether the path is obfuscated or not.

No, that would be impossible. Guessing an obfuscated path is the same problem as guessing an obfuscated password.

I feel like you're inventing APT-level script kiddies here. Your points have some validity, but I find your supporting evidence very suspect. Again, evidence please?

yodax commented 7 years ago

Easily? Care to submit a PR?

It's already implemented, a while ago by me and @Joshdata

guyzmo commented 7 years ago

Again, evidence please?

I won't lookup years of logs to give you the diversity of weird attack paths I'm getting just to make a point! I got better use of my time. I've seen a lot of weird and stupid scripts attacking my HTTP servers since the days of nimda, and I'm not collecting those.

I don't want to keep on trol^H^H^H^Harguing over this, spamming at least 12 participants. I believe I've made enough points to feed the discussion and the design of the feature.

bronson commented 7 years ago

@yodax right on.

@guyzmo I'm not asking for logs... just curious how much traffic {random}/admin get on your box. You make it sound like it's a lot, but to me that sounds like a very exceptional situation.

guyzmo commented 7 years ago

@bronson well, as always, it's a matter of fashion in the malware-script-kiddie industry. In the past I've seen my logs coloured with tons of different attack paths and queries, depending on the trendy malware of the time, including some random looking ones — were they actually random? I can't remember — but that remark was only to illustrate the bottom line.

But as I said, we don't need to fear script-kiddies-wide-reaching-malwares, at least not until MIAB has enough traction to become a plausible target. We neither fear brute force. What we can fear are exploits based on bugs we missed or patches we forgot about, or leak of the user's credentials/tokens, through a diverse range of exploits we can't predict (remember heartbleed?).

This is why client certificate and/or 2FA are the best ideas to protect the users, and get as many eyes as possible on the code to find bugs as well.

msgerbs commented 7 years ago

I agree with @guyzmo here. One of the most fundamental concepts of security is that security through obscurity is not security at all. Changing the admin panel URL is just an annoyance which, by definition, provides no actual security.

Client certificates or 2FA are the best suggestions I've seen here, and the only counter argument I can see is that they're either not being worked on or difficult to use. Neither is exceptionally difficult to use if designed well, surely no more difficult than setting up certificate authentication for SSH which MIAB expects the user to do.

saudiqbal commented 4 years ago

I would also like to see this implemented, choosing my own admin page on installation. Admin page is open to attacks.

h8h commented 4 years ago

I patched the default nginx config for example:

diff --git a/conf/nginx-primaryonly.conf b/conf/nginx-primaryonly.conf
index 288fce4..a1495d6 100644
--- a/conf/nginx-primaryonly.conf
+++ b/conf/nginx-primaryonly.conf
@@ -7,6 +7,10 @@
    rewrite ^/admin$ /admin/;
    rewrite ^/admin/munin$ /admin/munin/ redirect;
    location /admin/ {
+                allow  127.0.0.1;
+                # drop rest of the world
+                deny   all;
        proxy_pass http://127.0.0.1:10222/;
        proxy_set_header X-Forwarded-For $remote_addr;
        add_header X-Frame-Options "DENY";

Using that the /admin is no longer accessible by the public. Jumping on the box allows me to forward the nginx port. ssh box.example.org -L 8443:127.0.0.1:443

But this seems way too complicate for inexperienced users.

Maybe this could be opt-in, since almost every client system (windows, linux, macos) has a ssh client build-in and forwarding is not that complicated.

alexgleason commented 1 year ago

I'm less worried about the admin interface than I am about Nextcloud. That thing has CVEs every other week, and should probably be locked down behind a VPN for high-risk installations.