lejmr / iredmail-docker

iRedmail docker container
https://hub.docker.com/repository/docker/lejmr/iredmail
133 stars 59 forks source link

Possible to run under an existant nginx ? #70

Open m333w opened 4 years ago

m333w commented 4 years ago

Hi all,

First thank's for this image :)

I would like to run the container under an existant nginx, so i run the contener like this :

docker run -p 666:80 -p 999:443 \
           -h email.domain.tld \
           -e "MYSQL_ROOT_PASSWORD=strongpassword" \
           -e "SOGO_WORKERS=2" \
           -e "TZ=Europe/Paris" \
           -e "POSTMASTER_PASSWORD=strongpassword" \
           -e "IREDAPD_PLUGINS=['reject_null_sender', 'reject_sender_login_mismatch', 'greylisting', 'throttle', 'amavisd_wblist', 'sql_alias_access_policy']" \
           -v /srv/docker.app/iredmail/mysql:/var/lib/mysql \
           -v /srv/docker.app/iredmail/vmail:/var/vmail \
           -v /srv/docker.app/iredmail/clamav:/var/lib/clamav \
           --name=iredmail lejmr/iredmail:mysql-latest

My email.conf in nginx :

server {
    listen         80;
    server_name    email.domain.tld;
    return         301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name email.domain.tld;

    ssl on;
    ssl_certificate /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;

    access_log /var/log/nginx/iredmail-access.log combined;
    error_log /var/log/nginx/iredmail-error.log error;

    client_max_body_size 512M;

    location / {
        proxy_pass http://email.domain.tld:666/mail;
    }

    location /mail {
        proxy_pass http://email.domain.tld:666/mail;
    }

    location /iredadmin {
        proxy_pass http://email.domain.tld:666/iredadmin;
    }
    location /sogo {
        proxy_pass http://email.domain.tld:666/sogo;
    }
}

But when i go on email.domain.tld any browser say "bad redirection" What i am missing ?

Hope someone can help me

Best regards.

TitanFighter commented 4 years ago

Instead of

    location / {
        proxy_pass http://email.domain.tld:666/mail;
    }

    location /mail {
        proxy_pass http://email.domain.tld:666/mail;
    }

    location /iredadmin {
        proxy_pass http://email.domain.tld:666/iredadmin;
    }
    location /sogo {
        proxy_pass http://email.domain.tld:666/sogo;
    }

try

location /sogo {
    proxy_pass http://iredmail;
}

And probably you do not need this

-p 666:80 -p 999:443

because nginx directly communicates with container.

lejmr commented 4 years ago

Totally agree with @TitanFighter. I do have Nginx as a reverse proxy dealing with SSL on my server.

I am exporting the 443 port as 8443

-p 8443:443

then my nginx locaton section is as follows:

    location / {
        proxy_pass https://127.0.0.1:8443;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto https;
        proxy_set_header        X-Forwarded-Port 443;
    }

Hope this helps

BTW this is my full configuraton:

server {
    listen       80;
    listen       [::]:80;
        server_name mail.example.com;

        location / {
        return 301 https://$server_name$request_uri;
    }
    }

server {
    listen       127.0.0.1:10443 ssl;

        server_name mail.example.com;
        client_max_body_size 500M;

    # Logs
    error_log /var/log/nginx/mail.example.com.error.log warn;
    access_log  /var/log/nginx/mail.example.com.access.log combined;

    # SSLv2 and SSLv3
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    # Configuration of certificates
    ssl_certificate /etc/letsencrypt/live/mail.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mail.example.com/privkey.pem;

    # The Cipher Suite
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:1m;

    ssl_session_timeout  10m;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";

    # enable ocsp stapling (mechanism by which a site can convey certificate revocation information to visitors in a privacy-preserving, scalable manner)
    # http://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox/
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/mail.example.com/fullchain.pem;

    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
    # ssl_dhparam /etc/ssl/certs/dhparam.pem;

    #6Months of HSTS
    add_header Strict-Transport-Security max-age=15768000;

    location / {
        proxy_pass https://127.0.0.1:8443;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto https;
        proxy_set_header        X-Forwarded-Port 443;
    }
}
uwla commented 4 years ago

Can yo u say where the configuration file is? I'd like to register iRedmail on mail.mydomainexample.com but I'm having trouble with that.

I tried the following:

docker run -d --expose 80 --expose 443 \
            -e VIRTUAL_HOST=mail.mydomainexample.com\
           -e "MYSQL_ROOT_PASSWORD=strongpassword" \
           -e "SOGO_WORKERS=1" \
           -e "TZ=Europe/Prague" \
           -e "POSTMASTER_PASSWORD=strongpassword" \
           -e "IREDAPD_PLUGINS=['reject_null_sender', 'reject_sender_login_mismatch', 'greylisting', 'throttle', 'amavisd_wblist', 'sql_alias_access_policy']" \
           -v /srv/iredmail/mysql:/var/lib/mysql \
           -v /srv/iredmail/vmail:/var/vmail \
           -v /srv/iredmail/clamav:/var/lib/clamav \
           --name=iredmail lejmr/iredmail:mysql-latest

but did not work. Any help would be appreciated :)

Totally agree with @TitanFighter. I do have Nginx as a reverse proxy dealing with SSL on my server.

I am exporting the 443 port as 8443

-p 8443:443

then my nginx locaton section is as follows:

    location / {
        proxy_pass https://127.0.0.1:8443;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto https;
        proxy_set_header        X-Forwarded-Port 443;
    }

Hope this helps

BTW this is my full configuraton:

server {
    listen       80;
    listen       [::]:80;
        server_name mail.example.com;

        location / {
        return 301 https://$server_name$request_uri;
    }
    }

server {
    listen       127.0.0.1:10443 ssl;

        server_name mail.example.com;
        client_max_body_size 500M;

    # Logs
    error_log /var/log/nginx/mail.example.com.error.log warn;
    access_log  /var/log/nginx/mail.example.com.access.log combined;

    # SSLv2 and SSLv3
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    # Configuration of certificates
    ssl_certificate /etc/letsencrypt/live/mail.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mail.example.com/privkey.pem;

    # The Cipher Suite
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:1m;

    ssl_session_timeout  10m;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";

    # enable ocsp stapling (mechanism by which a site can convey certificate revocation information to visitors in a privacy-preserving, scalable manner)
    # http://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox/
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/mail.example.com/fullchain.pem;

    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
    # ssl_dhparam /etc/ssl/certs/dhparam.pem;

    #6Months of HSTS
    add_header Strict-Transport-Security max-age=15768000;

    location / {
        proxy_pass https://127.0.0.1:8443;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto https;
        proxy_set_header        X-Forwarded-Port 443;
    }
}
lejmr commented 4 years ago

With what you got you already have all you need. I mean running that command you will propagate internal nginx to your host system, so if you point DNS over there you are done.

However, you also need to propagate other ports, e.g., 25, 587 for email server itself.

To the configuration. The docker image contains nginx already with following configuration

[root@mail iredmail]# cat /etc/nginx/sites-enabled/00-default.conf
#
# Note: This file must be loaded before other virtual host config files,
#
# HTTP
server {
    # Listen on ipv4
    listen 80;
    #listen [::]:80;

    server_name _;

    # Redirect all insecure http:// requests to https://
    return 301 https://$host$request_uri;
}
[root@mail iredmail]# cat /etc/nginx/sites-enabled/00-default-ssl.conf
#
# Note: This file must be loaded before other virtual host config files,
#
# HTTPS
server {
    listen 443 ssl;
    #listen [::]:443 ssl;
    server_name _;

    root /var/www/html;
    index index.php index.html;

    include /etc/nginx/templates/misc.tmpl;
    include /etc/nginx/templates/ssl.tmpl;
    include /etc/nginx/templates/iredadmin.tmpl;
    include /etc/nginx/templates/roundcube.tmpl;
    include /etc/nginx/templates/sogo.tmpl;
    include /etc/nginx/templates/netdata.tmpl;
    include /etc/nginx/templates/php-catchall.tmpl;
    include /etc/nginx/templates/stub_status.tmpl;
}
uwla commented 4 years ago

The DNS records are already pointing to the desirable subdomain, but iRedMail is still not working.

My goal is to have subdomains like mail.example.com, cloud.example.com, gitlab.example.com, and so on. So, I followed this tutorial and set a nginx proxy container. The nginx proxy listens to traffic on ports 80 and 443 and redirects it to the correct container (but is not working for iRedMail only).

iRedmail does work if, for example, I configure docker to redirect ports 8080 and 8443 in the host to ports 80 and 443 in the container, respectively.

I guess the problem is that there are two nginx: one in the nginx proxy, and the other in your iRedMail docker image. Could you help to tackle this? I'm quite lost because I've just started using Docker and Nginx three days ago (before, I used to use the traditional LAMP setup).

TitanFighter commented 4 years ago

I also use mail.domain.com. If you wish I can share docker compose settings tomorrow. If you do not want to use docker compose then at least you can see how it works and can convert docker compose settings back to just simple docker yourself.

uwla commented 4 years ago

Yes, please share the compose settings :) that will be helpful

TitanFighter commented 4 years ago

@AndreSouzaAbreu

docker-compose.nginx-proxy-w-le.yml

# HOW TO USE:

# 1. Download latest nginx.tmpl (save next to this docker-compose file):
#    curl https://raw.githubusercontent.com/jwilder/nginx-proxy/master/nginx.tmpl > ./nginx.tmpl
# 2. Run docker-compose: docker-compose -f ./docker-compose.nginx-proxy-w-le.yml up -d

# Based on: https://github.com/buchdag/letsencrypt-nginx-proxy-companion-compose

version: '3.5'
services:
  nginx-proxy:
    image: nginx
    container_name: nginx-proxy-container
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - conf:/etc/nginx/conf.d
      - vhost:/etc/nginx/vhost.d
      - html:/usr/share/nginx/html
      - certs:/etc/nginx/certs:ro
    labels:
      - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy"
    restart: always

  docker-gen:
    image: jwilder/docker-gen
    container_name: nginx-proxy-gen-container
    command: -notify-sighup nginx-proxy-container -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
    depends_on:
      - nginx-proxy
    volumes:
      - conf:/etc/nginx/conf.d
      - vhost:/etc/nginx/vhost.d
      - certs:/etc/nginx/certs:ro
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro
    labels:
      - "com.github.jrcs.letsencrypt_nginx_proxy_companion.docker_gen"
    restart: always

  letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: nginx-proxy-le-container
    depends_on:
      - nginx-proxy
      - docker-gen
    volumes:
      - vhost:/etc/nginx/vhost.d
      - html:/usr/share/nginx/html
      - certs:/etc/nginx/certs
      - /var/run/docker.sock:/var/run/docker.sock:ro
    restart: always

volumes:
  conf:
  vhost:
  html:
  certs:

networks:
  default:
    name: nginx-proxy

docker-compose.iredmail_lejmr.yml

version: '3.5'
services:
  iredmail:
    image: lejmr/iredmail:mysql-latest
    container_name: iredmail-container
    restart: unless-stopped
    hostname: mail.yourdomain.com
    privileged: yes
    ports:
      - "25:25"
      - "587:587"
    volumes:
      - /var/www/mail/mysql:/var/lib/mysql
      - /var/www/mail/vmail:/var/vmail
      - /var/www/mail/clamav:/var/lib/clamav
      - /etc/localtime:/etc/localtime:ro
    environment:
      - MYSQL_ROOT_PASSWORD=SuperSecretMySQLPassword
      - POSTMASTER_PASSWORD={PLAIN}SuperSecretPassword
      - IREDAPD_PLUGINS="['reject_null_sender', 'reject_sender_login_mismatch', 'greylisting', 'throttle', 'amavisd_wblist', 'sql_alias_access_policy']"
      - VIRTUAL_HOST=mail.yourdomain.com
      - VIRTUAL_PORT=443
      - VIRTUAL_PROTO=https
      - SSL_POLICY=Mozilla-Modern
      - LETSENCRYPT_HOST=mail.yourdomain.com
      - LETSENCRYPT_EMAIL=admin@yourdomain.com

networks:
  default:
    external:
      name: nginx-proxy

Run both, the 1st one is docker-compose.nginx-proxy-w-le.yml and then docker-compose.iredmail_lejmr.yml. As a result you will get iredmail encrypted by LetsEncrypt.

Using nginx-proxy network you can use proxy from docker-compose.nginx-proxy-w-le.yml for any other dockerized container, so next to iredmail container you can add for example your web-server container.

Change mail.yourdomain.com, admin@yourdomain.com, SuperSecretMySQLPassword and SuperSecretPassword to the ones you need.

uwla commented 4 years ago

@TitanFighter thank you! that worked! But for some reason I cann't login into posmaster@mydomain.com .. could you send me a message (andresouzaabreu.dev at gmail.com) for us to discuss it elsewhere? To avoid flooding here

TitanFighter commented 4 years ago

I have just one idea - from this example POSTMASTER_PASSWORD={PLAIN}SuperSecretPassword - you removed {PLAIN} part. You should leave this part unchanged and should change just SuperSecretPassword

TitanFighter commented 4 years ago

@AndreSouzaAbreu just had your problem for some reason.

Here is the instruction how to reset password.

Basically you need to docker exec -it iredmail-container-name bash, then mysql -u root in order to open sql terminal and continue with steps from the link above.

uwla commented 4 years ago

Thanks @TitanFighter , I will try that out.

I have a guess about why this is happening. I had a similar problem with passwords when seeding a database of a webserver. The passwords were stored in plain text in the databse. When the user tried to login, the password the user entered would be hashed and then compared to the value in the database. If the values were different, the user wouldn't login. Since the values seeded into the database were not hashed, the user accounts that were created in the seeding process would never be able to login. I think that a similar thing is happening here with iRedMail. In the case of my webserver, I was able to solve this by hashing the passwords in the seeding process.