1

Topic: reverse-proxy under Nginx ?

==== Required information ====
- iRedMail version (check /etc/iredmail-release):
- Linux/BSD distribution name and version:
- Store mail accounts in which backend (LDAP/MySQL/PGSQL):
- Web server (Apache or Nginx):
- Manage mail accounts with iRedAdmin-Pro?
- Related log if you're reporting an issue:
====
Hi,
Is somebody of  the community do have any experience  concerning the implementation for  an reverse-proxy (running  with Nginx) as front-end for our iRedmail server ?

Thx

----

Spider Email Archiver: On-Premises, lightweight email archiving software developed by iRedMail team. Supports Amazon S3 compatible storage and custom branding.

2

Re: reverse-proxy under Nginx ?

Are you trying to proxy IMAP connections or just port 80/443 connections for iredadmin, roundcube, and sogo?

3

Re: reverse-proxy under Nginx ?

We use HAProxy.

4 (edited by Thierry 2017-01-12 12:49:01)

Re: reverse-proxy under Nginx ?

time4e wrote:

Are you trying to proxy IMAP connections or just port 80/443 connections for iredadmin, roundcube, and sogo?

Just port 443 for Sogo ...
I am checking the HAproxy ...

Thx

5

Re: reverse-proxy under Nginx ?

Hi,

Are you using HAproxy in front of an iRedmail server ?

Thx

6

Re: reverse-proxy under Nginx ?

Thierry wrote:

Are you using HAproxy in front of an iRedmail server ?

Yes, our cluster solution has 2 frontend servers which run HAProxy + KeepAlived + Dovecot Director.

7

Re: reverse-proxy under Nginx ?

Because I would like  to use  HAproxy in front of my iredmail, but I am stuck ...
Can I post my config ? I ask you because this is not an iRedmail pb smile

Thx

8

Re: reverse-proxy under Nginx ?

yes no ? smile

9 (edited by time4e 2017-01-14 01:51:06)

Re: reverse-proxy under Nginx ?

nginx also works well as a reverse proxy. Here is an example of a vhost for nginx

server {

    listen 80;
    server_name webmail.domain.com;
    return         301 https://$server_name$request_uri;
}

 server {

       listen         443 ssl;
       server_name    webmail.domain.com;

        location ~phpmyadmin* {
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $host;
        proxy_pass http://webmail;
}



      ssl_certificate         /etc/nginx/certs/webmail.domain.com.chained.crt;
      ssl_certificate_key     /etc/nginx/certs/webmail.domain.com.key;
      ssl_session_cache  builtin:1000  shared:SSL:10m;
      ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
      ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-   SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-A$
      ssl_prefer_server_ciphers on;
      ssl_dhparam /usr/local/etc/nginx/certs/dhparams.pem;
      #add more option if using cert from CA see SSL hardening https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-load-balancing-with-ssl-termination



    location / {

        proxy_pass http://webmail;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_cache my_cache;
        proxy_cache_revalidate on;
        proxy_cache_min_uses 3;
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
        proxy_cache_lock on;
        proxy_set_header Host $host;
        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 $scheme;

    }
}

proxy.conf

proxy_buffering         on;
proxy_redirect          off;
proxy_set_header        Host            $host;
proxy_set_header        X-Real-IP       $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size    10m;
client_body_buffer_size 128k;
proxy_connect_timeout   90;
proxy_send_timeout      90;
proxy_read_timeout      90;
proxy_buffers           100 8k;
add_header              X-Cache $upstream_cache_status;

nginx.conf

    user  www;
    worker_processes  1;
    error_log  /var/log/nginx/error.log;

    events {
    worker_connections  1024;
    }

    http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    '$status $body_bytes_sent "$http_referer" '
    '"$http_user_agent" "$http_x_forwarded_for"';
    access_log /var/log/nginx/access.log;

    sendfile        on;
    keepalive_timeout  65;

    # Nginx cache configuration
    proxy_cache_path /var/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
    proxy_cache my_cache;
    proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
    proxy_temp_path     /var/nginx/cache/tmp;
    proxy_cache_key     "$scheme$host$request_uri";

    gzip  on;

    server {
    #listen       80;
    server_name  _;

    location /nginx_status {

    stub_status on;
    access_log off;
    }

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
    root   /usr/local/www/nginx-dist;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:8080
    #
    location ~ \.php$ {
    proxy_pass   http://127.0.0.1:8080;
    include /usr/local/etc/nginx/proxy.conf;
    }
    }

    include /usr/local/etc/nginx/vhost/*;

    }

In this example nginx will also offload ssl. hope this helps

10

Re: reverse-proxy under Nginx ?

Thx for the tips, but I  have spent to much time trying to configure HAproxy smile
Half of it is now working, I  am able to reach  my web server through my HAproxy.
Still do not work  for iRedmail.

My config:

frontend email-http
        mode http
        bind :888 ssl crt  /etc/ssl/private/full_certs.crt
        option httplog
        default_backend email-http

backend email-http
        mode http
        option  httplog
        option forwardfor
        http-request set-header X-Forwarded-Port  %[dst_port]
        http-request  add-header X-Forwarded-Proto https if { ssl_fc }
        option httpchk HEAD /HTTP/1.1\r\nHost:localhost
        option http-server-close
        server node1 private_ip_number:888 ssl verify none

This is a past and copy from the config who is working for my web server.

Error message:

502 Bad Gateway
The server returned an invalid or incomplete  response

From the logs of HAproxy:

Jan 13 21:19:21 proxy haproxy[26767]: ip_number:38224 [13/Jan/2017:21:19:21.881] email-http~ email-http/node1 0/0/34/-1/35 502 205 - - SH-- 1/1/0/0/0 0/0 "GET /SOGo/ HTTP/1.1"

From the server side:

haproxy_ip - - [13/Jan/2017:20:19:16 +0100] "GET /SOGo/ HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5 Build/MMB29T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Mobile Safari/537.36"
haproxy_ip - - [13/Jan/2017:20:25:18 +0100] "GET /SOGo/ HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5 Build/MMB29T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.85 Mobile Safari/537.36"

Any ideas ??
Thx

11

Re: reverse-proxy under Nginx ?

ours:

frontend http
    bind :80
    # Enable http mode
    mode http

    # Passive HTTP connection closing
    option httpclose

    # Enable insertion of the X-Forwarded-For header to requests sent to servers
    option forwardfor

    # Strip the header off requests, used to fix the HTTPROXY vulnerability.
    # Reference: https://httpoxy.org/
    http-request del-header Proxy

    # adds the HTTP header to the end of the incoming request
    reqadd X-Forwarded-Proto:\ http

    default_backend bk_web

frontend https
    #
    # Let HAProxy handle SSL, not backend servers.
    #
    bind :443 ssl crt /etc/haproxy/ca-cert-key.pem
    # Enable http mode
    mode http

    # Passive HTTP connection closing
    option httpclose

    # Enable insertion of the X-Forwarded-For header to requests sent to servers
    option forwardfor

    # Delete Proxy header due to HTTPoxy vulnerability
    http-request del-header Proxy

    # adds the HTTPS header to the end of the incoming request
    reqadd X-Forwarded-Proto:\ https

    # HSTS header: security policy to prevent against downgrade attacks
    #rspadd Strict-Transport-Security:\ max-age=31536000

    default_backend bk_web

backend bk_web
    balance roundrobin

    # Enable http mode
    mode http

    # Redirect all http traffic to https
    redirect scheme https if !{ ssl_fc }
    
    # Session stick
    stick-table type ip size 200k expire 1h peers frontend_peers
    stick on src

    # reduces latency between HAProxy and end users by closing connections but
    # maintaining keep-alives.
    option http-server-close

    # HTTP check, tries to get /
    option httpchk GET /

    server u7 u7.iredmail.org:80 check on-marked-down shutdown-sessions
    server u8 u8.iredmail.org:80 check on-marked-down shutdown-sessions
    server u9 u9.iredmail.org:80 check on-marked-down shutdown-sessions

12 (edited by Thierry 2017-01-14 18:41:15)

Re: reverse-proxy under Nginx ?

Working reverse proxy using HAproxy:

frontend email-ssl
        mode http
        bind :888 ssl crt  /etc/ssl/private/full_certs.crt
        option httplog
        option httpclose
        http-request del-header Proxy
        rspadd  Strict-Transport-Security:\ max-age=15768000
        default_backend email-web-ssl

backend email-web-ssl
        mode http
        option  httplog
        option forwardfor
        http-request set-header X-Forwarded-Port  %[dst_port]
        http-request  add-header X-Forwarded-Proto https if { ssl_fc }
        redirect scheme https if !{ ssl_fc }
        option httpchk HEAD /HTTP/1.1\r\nHost:localhost
        option http-server-close
        server node_email_ssl iredmail_ip:443 ssl verify none

Thx

13

Re: reverse-proxy under Nginx ?

Thierry wrote:

        bind :888 ssl crt  /etc/ssl/private/full_certs.crt
...
        server node_email_ssl iredmail_ip:443 ssl verify none

If you already let HAProxy handle the https, might be better connect to port 80 on backend server for better performance.

14

Re: reverse-proxy under Nginx ?

Thx I will have a look on it  ...
Btw, "iRedAdmin" is accessible from outside my  network, I would prefer  not ... Any  idea ?

Thx

15

Re: reverse-proxy under Nginx ?

Thierry wrote:

Btw, "iRedAdmin" is accessible from outside my  network, I would prefer  not ... Any  idea ?

You sure know Apache/Nginx have ACL support, right? big_smile