mailcow / mailcow-dockerized

mailcow: dockerized - 🐮 + 🐋 = 💕
https://mailcow.email
GNU General Public License v3.0
8.58k stars 1.15k forks source link

Change main URL for Admin panel #786

Closed lucianlazar1983 closed 6 years ago

lucianlazar1983 commented 6 years ago

Hi there, how can I change the main URL? I would like that whoever reaches mail.host.com instead of seeing the MailCow login, instead redirect to /sogo, and for administrative login use for an instance /admin. Is it possible? Thank you

chaosbunker commented 6 years ago

why not forward host.com/webmail to mail.host.com/SOGo instead?

I think the way it is set up right now is good.

lucianlazar1983 commented 6 years ago

My problem is not that, the problem is whoever try to access https://server_host will default to the login page. I am trying to hide the login page and make it accessible only with a custom url

Braintelligence commented 6 years ago

You do realize, that people need that page to set up some personal stuff for their mail account?

lucianlazar1983 commented 6 years ago

I perfectly realize, but i know my customers very well and they only need a webmail and change the password (that si done from sogo right?)

chaosbunker commented 6 years ago

No, that is done via mailcow ui

lucianlazar1983 commented 6 years ago

ok, no problem with that and the user can use /admin in order to access that. My purpose is to not have the admin UI login as the default page for server_address. Can it be done without being overwritten by future updates?

Braintelligence commented 6 years ago

You change the password via Mailcow ui. People also see the mail app configuration instructions there and can create aliases. These are core features...

Braintelligence commented 6 years ago

You can try forwarding or change the nginx.conf and stash the changes. Pop them after an update, as we did before we had a update.sh script.

Still the user and "admin" login to manage the mail account on a meta level are the same page. I don't see the use-case yet trying to hide this, since people will want to be able to change their password and set up aliases.

All my users wanted to be able to do this. Especially the temporary spam alias can be very helpful.

lucianlazar1983 commented 6 years ago

I did not say that this should be a core feature or modification of the product. I simply asked if there is a way for ME to change this behavior without loose changes over upgrades.

lucianlazar1983 commented 6 years ago

of course, this is useful, but my customers could get confused on where they should input their details in order to read emails. Unfortunately, they are not technical people and the barely know how to deal with a webmail (this is a sad reality)

Braintelligence commented 6 years ago

You can sell the Mailcow UI as an entrance to SOGo, since it is available as app there. This could prove advantageous in the future when Mailcow starts to incorporate other apps there.

reinistihovs commented 6 years ago

Easy way to limit acces to mailcow UI only from one IP:

add this in mailcow-dockerized/data/web/index.php after "<?php" first line.

if ($_SERVER['REMOTE_ADDR'] != "Your.Public.IP.Address"){ header("Location: ./SOGo/"); exit(); }

This way everyone will be redirected to SOGo and wont have access to the admin panel at all, and for user password change you can enable it in /mailcow-dockerized/data/conf/sogo/sogo.conf by setting SOGoPasswordChangeEnabled = yes; ( restart SOGo afterwards) tested, and works

mkuron commented 6 years ago

Duplicate of #393

farzadha2 commented 1 year ago

@reinistihovs thank you really awesome way, but is there a way to add more public address? i tried adding the , then another public IP address but didnt work

maul75 commented 1 year ago

For multiple use this:

if (!in_array($_SERVER['REMOTE_ADDR'], [ '1.1.1.1', '1.2.2.2' ])) { header("Location: ./SOGo/"); exit(); }

farzadha2 commented 1 year ago

Hi @maul75 thanks for the reply, is it possible to add the remote network? as 192.168.1.0/24? i was looking at the manual page https://www.php.net/manual/en/reserved.variables.server.php but couldnt seem to find it the correct format

maul75 commented 1 year ago

Try this:

function ipCIDRCheck($IP, $CIDR) { list ($net, $mask) = explode('/', $CIDR); $ip_net = ip2long($net); $ip_mask = ~((1 << (32 - $mask)) - 1); $ip_ip = ip2long($IP); return (($ip_ip & $ip_mask) == ($ip_net & $ip_mask)); }

if (!ipCIDRCheck($_SERVER['REMOTE_ADDR'], "192.168.1.0/24")) { header("Location: ./SOGo/"); exit(); }

farzadha2 commented 1 year ago

@maul75 Thank you so much that did the trick

StraderCGN commented 1 year ago

I've found out another way to secure the admin page and use an own URLs for SOG and admin. Just create a reverse proxy like in the offical documentation of mailcow. The only part is to add a rewrite rule for SOG. In my case:

vhost: mail.yourdomain.com

 RewriteEngine On
 RewriteCond %{HTTP_HOST} ^mail\.yourdomain\.com$ [NC]
 RewriteRule ^/$ /SOGo [R=301,L]

[note: its also possible to set a custom hostname for your SOG like:
RewriteRule ^/$ https://webmail.yourdomain.com/SOGo$1 [R=301,L]

Remember to set the ProxyPass for ActiveSync!

vhost: mailadmin.yourdomain.com

<Location/>
    Require ip [YourIP]
</Location>

The whole config would be:

<VirtualHost *:80>
  ServerName mail.yourdomain.com
  ServerAlias autodiscover.*
  ServerAlias autoconfig.*
  Redirect permanent / https://mail.yourdomain.com
  RewriteEngine on
  RewriteCond %{SERVER_NAME} =mail.yourdomain.com
  RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

<VirtualHost *:443>
  ServerName mail.yourdomain.com
  ServerAlias autodiscover.*
  ServerAlias autoconfig.*
  SSLEngine on

  ProxyPass /Microsoft-Server-ActiveSync http://127.0.0.1:8080/Microsoft-Server-ActiveSync connectiontimeout=4000
  ProxyPassReverse /Microsoft-Server-ActiveSync http://127.0.0.1:8080/Microsoft-Server-ActiveSync

  RewriteEngine On
  RewriteCond %{HTTP_HOST} ^mail\.yourdomain\.com$ [NC]
  RewriteRule ^/$ https://webmail.yourdomain.com/SOGo$1 [R=301,L]

  #RewriteRule ^/$ /SOGo [R=301,L]  <-- You have to use this rewrite rule on vhost webmail.yourdomain.com, if you want to use a separated hostname. Otherwise, replace the rule above with this one.

  ProxyPass / http://127.0.0.1:8080/
  ProxyPassReverse / http://127.0.0.1:8080/

  ProxyPreserveHost On
  ProxyAddHeaders On
  RequestHeader set X-Forwarded-Proto "https"

  SSLCertificateFile /opt/mailcow-dockerized/data/assets/ssl/mail.yourdomain.com/cert.pem
  SSLCertificateKeyFile /opt/mailcow-dockerized/data/assets/ssl/mail.yourdomain.com/key.pem
</VirtualHost>

The vhost config for mailadmin is basicly this:

<VirtualHost *:80>
    ServerName mailadmin.yourdomain.com
    Redirect permanent / https://mailadmin.yourdomain.com/
    RewriteEngine on
    RewriteCond %{SERVER_NAME} =mailadmin.yourdomain.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

<VirtualHost *:443>
  ServerName mailadmin.yourdomain.com
  SSLEngine on

  ServerAlias autodiscover.*
  ServerAlias autoconfig.*

  <Location />
    Require ip [yourIP]
  </Location>

  # Redirect for SOG
  RewriteEngine On
  RewriteCond %{HTTP_HOST} ^mailadmin\.yourdomain\.com$ [NC]
  RewriteRule ^/SOGo https://webmail.yourdomain.com/SOGo$1 [R=301,L]

  ProxyPass / http://127.0.0.1:8080/
  ProxyPassReverse / http://127.0.0.1:8080/
  ProxyPreserveHost On
  ProxyAddHeaders On
  RequestHeader set X-Forwarded-Proto "https"

  SSLCertificateFile /etc/letsencrypt/live/mailadmin.yourdomain.com/fullchain.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/mailadmin.yourdomain.com/privkey.pem
  Include /etc/letsencrypt/options-ssl-apache.conf

</VirtualHost>

Yes, I know that it's not really necessary to use a separate hostname for the SOG just to forward mail.yourdomain.com to it. I just thought it looked nicer that way. It's definitely important to secure the admin page with a Location Rule and Require IP.

Originally, I didn't want to publish the web ports for my Mailcow to the internet at all. It just had the side effect that the renewal of the LetsEncrypt certificates couldn't run automatically because I had blocked ports 80 and 443... With this change, I at least feel safe enough that I let the web ports open.

killmasta93 commented 1 year ago

hi @maul75 quick question if i wanted to add another segment IP to this code? would it be like this?


function ipCIDRCheck($IP, $CIDR) {
list ($net, $mask) = explode('/', $CIDR);
$ip_net = ip2long($net);
$ip_mask = ~((1 << (32 - $mask)) - 1);
$ip_ip = ip2long($IP);
return (($ip_ip & $ip_mask) == ($ip_net & $ip_mask));
}

if (!ipCIDRCheck($_SERVER['REMOTE_ADDR'], "192.168.1.0/24" "192.168.7.0/24" )) {
header("Location: ./SOGo/");
exit();
}

Thanks

maul75 commented 1 year ago

Easiest and quickest solution will maybe be this for multiple segments:

function ipCIDRCheck($IP, $CIDR) { list ($net, $mask) = explode('/', $CIDR); $ip_net = ip2long($net); $ip_mask = ~((1 << (32 - $mask)) - 1); $ip_ip = ip2long($IP); return (($ip_ip & $ip_mask) == ($ip_net & $ip_mask)); }

foreach ([ "192.168.1.0/24", "192.168.7.0/24" ] as $CIDR) { if (!ipCIDRCheck($_SERVER['REMOTE_ADDR'], $CIDR)) { header("Location: ./SOGo/"); exit(); } }