Skip to content

Instantly share code, notes, and snippets.

@taddev
Last active July 27, 2023 10:49
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
  • Save taddev/7275873 to your computer and use it in GitHub Desktop.
Save taddev/7275873 to your computer and use it in GitHub Desktop.
Nginx reverse proxy to Exchange 2010/2013
server {
listen 80;
#listen [::]:80;
server_name mail.gwtest.us autodiscover.gwtest.us;
return 301 https://$host$request_uri;
}
server {
listen 443;
#listen [::]:443 ipv6only=on;
ssl on;
ssl_certificate /etc/ssl/nginx/mail.gwtest.us.crt;
ssl_certificate_key /etc/ssl/nginx/mail.gwtest.us.open.key;
ssl_session_timeout 5m;
server_name mail.gwtest.us;
location / {
return 301 https://mail.gwtest.us/owa;
}
proxy_read_timeout 360;
proxy_pass_header Date;
proxy_pass_header Server;
#proxy_pass_header Authorization;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location ~* ^/owa { proxy_pass https://exch1.test.local; }
location ~* ^/Microsoft-Server-ActiveSync { proxy_pass https://exch1.test.local; }
location ~* ^/ecp { proxy_pass https://exch1.test.local; }
location ~* ^/rpc { proxy_pass https://exch1.test.local; }
#location ~* ^/mailarchiver { proxy_pass https://mailarchiver.local; }
error_log /var/log/nginx/owa-ssl-error.log;
access_log /var/log/nginx/owa-ssl-access.log;
}
@adamjs83
Copy link

@jbostoen did you make sure it works without nginx in front? I spent a lot of time on this and it turned out to be an exchange issue that needed fixing.

@adamjs83
Copy link

I finally got this working and posted the detailed instructions on my blog. http://blog.adamjoshuasmith.com/deploying-exchange-2016-behind-nginx-free/

@jbostoen I believe your issue is that you are using an Admin user account which will not work with Activesync. try creating a new user who is only in the Domain User group and test active sync with that mailbox. If it works, you know where your problem is.

@jbostoen
Copy link

Just stumbling back on this. Desktop Outlook is what I need to get working...
Thanks for the great write-up!

@Martinvdm
Copy link

I have tried this config from tigunov and from adamjs83 but both configs are not working with outlook anywhere and Exchange 2013 with RPC over HTTP. Nginx logging is generating 401 for RPC_IN_DATA and Outlook keeps asking for login credentials. Somebody know what i am doing wrong here?

@enoch85
Copy link

enoch85 commented Jun 15, 2019

@KodySalak
Copy link

I have tried this config from tigunov and from adamjs83 but both configs are not working with outlook anywhere and Exchange 2013 with RPC over HTTP. Nginx logging is generating 401 for RPC_IN_DATA and Outlook keeps asking for login credentials. Somebody know what i am doing wrong here?

RPC doesn't work with the free version... the last time I tried to go down this hole it led me to that answer.

Just stumbling back on this. Desktop Outlook is what I need to get working...
Thanks for the great write-up!

Did you ever find out what was causing your FolderSync issues? I get a 502 bad gateway.

@Alex-JTI
Copy link

Alex-JTI commented Dec 9, 2020

RPC doesn't work with the free version...

I'm running Exchange 2010 with RPC over HTTP. All is working well including RPC and no 401 is generated.
The config is similar to https://gist.github.com/enoch85/573dac9005f0c8f1b826cc22e520e0ae with the only difference that I also pass 2 more headers:
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;

@enoch85
Copy link

enoch85 commented Dec 9, 2020

Thanks @Alex-JTI, it's now updated!

@mamama1
Copy link

mamama1 commented Jul 27, 2021

@Alex-JTI @enoch85 is this working with NTLM or with Basic authentication? I was thinking nginx free cannot handle NTLM...?!
Thanks!

@Owirtifo
Copy link

Hello! I want to make a reverse proxy for MS Exchange using nginx with the spnego-http-auth-nginx-module module. How to make nginx check clients using certificates, and if they passed, then authorize them on MS Exchange using Kerberos. Clients must connect to MS Exchange via Activesync. Configuration example:

server {

server_name rp.blablabla.com;
listen 443 ssl;
ssl_certificate /etc/ssl/nginx/cert.pem;
ssl_certificate_key /etc/ssl/nginx/cert.pem;
ssl_session_timeout 5m;
client_max_body_size 2G;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_verify_client on;
ssl_verify_depth 5;
ssl_client_certificate /etc/ssl/nginx/cert.pem;

proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

#keealive is only in 1.1 supported, default is 1.
proxy_http_version 1.1;

location ~* ^/Microsoft-Server-ActiveSync {
proxy_pass https://exchange.blablabla.local;
auth_gss on;
auth_gss_realm BLABLABLA.LOCAL;
auth_gss_keytab /etc/nginx/spnego.keytab;
auth_gss_service_name HTTP/rp-mail;
auth_gss_allow_basic_fallback off;
}
Maybe there is another way to implement
the connection of remote clients via Activesync with certificate verification, as it is implemented on the Microsoft Forefront Threat Management Gateway?

@MakoWish
Copy link

MakoWish commented Jan 6, 2023

@Alex-JTI Thank you! Your solution worked for me. I made some slight modifications, because I am using it for Microsoft RemoteApp instead of Exchange, but same RPC over HTTP situation.

@tomasenskede
Copy link

I'm experiencing a similar problem... Is there anyone available who can offer me assistance?

I have configured Ngnix Reverse Proxy within my Docker on Proxmox. Within my network, I have Exchange 2016, and my users are accessing it remotely using Outlook, mobile ActiveSync, and OWA.

OWA is functioning correctly with my new setup, but ActiveSync and Outlook (RPC/MAPI over HTTP) are not working.

Is there a way to resolve this issue and make them function properly? I would greatly appreciate any tips or guidance. Thank you very much!

@tigunov
Copy link

tigunov commented May 30, 2023

I'm experiencing a similar problem... Is there anyone available who can offer me assistance?

I have configured Ngnix Reverse Proxy within my Docker on Proxmox. Within my network, I have Exchange 2016, and my users are accessing it remotely using Outlook, mobile ActiveSync, and OWA.

OWA is functioning correctly with my new setup, but ActiveSync and Outlook (RPC/MAPI over HTTP) are not working.

Is there a way to resolve this issue and make them function properly? I would greatly appreciate any tips or guidance. Thank you very much!

proxy_buffering off;
should fix the issue with RPC/MAPI over HTTP

@tomasenskede
Copy link

/etc/nginx/nginx.conf

image

is this correct? am I in the correct config?

Where should I add "proxy_buffering off;" ?

the certs, arnt present... do I have to generate these manually? I have generated certs in the GUI...
/etc/ssl/nginx/www.dmz.se.crt;
/etc/ssl/nginx/www.dmz.se.key;

@Edrard
Copy link

Edrard commented May 30, 2023

Do not use nginx for Exchange, it's not work correctly, better use haproxy

frontend ft_https
                bind *:443 ssl crt /etc/haproxy/emailcert.pem
                reqadd X-Forwarded-Proto:\ https
                default_backend bk_exchange

                acl ft_owa      hdr(host) -i email.example.com
                use_backend bk_exchange if ft_owa

backend bk_exchange
                acl path_root url_len 1
                acl path_exchange path_beg -i /autodiscover /owa /oab /ews /public /microsoft-server-activesync /rpc /mapi /favicon.ico
                http-request deny unless path_exchange OR path_root
                server exchange 10.0.25.25:443 check ssl verify none

@tomasenskede
Copy link

Thanks, HA

Do not use nginx for Exchange, it's not work correctly, better use haproxy

frontend ft_https
                bind *:443 ssl crt /etc/haproxy/emailcert.pem
                reqadd X-Forwarded-Proto:\ https
                default_backend bk_exchange

                acl ft_owa      hdr(host) -i email.example.com
                use_backend bk_exchange if ft_owa

backend bk_exchange
                acl path_root url_len 1
                acl path_exchange path_beg -i /autodiscover /owa /oab /ews /public /microsoft-server-activesync /rpc /mapi /favicon.ico
                http-request deny unless path_exchange OR path_root
                server exchange 10.0.25.25:443 check ssl verify none

parsing [/usr/local/etc/haproxy/haproxy.cfg:3] : The 'reqadd' directive is not supported anymore since HAProxy 2.1. Use 'http-request add-header' instead.

I tested but your config did genereate an error...

regarding the certs, can I use the certs generated by Nginix?

@tomasenskede
Copy link

I'm experiencing a similar problem... Is there anyone available who can offer me assistance?
I have configured Ngnix Reverse Proxy within my Docker on Proxmox. Within my network, I have Exchange 2016, and my users are accessing it remotely using Outlook, mobile ActiveSync, and OWA.
OWA is functioning correctly with my new setup, but ActiveSync and Outlook (RPC/MAPI over HTTP) are not working.
Is there a way to resolve this issue and make them function properly? I would greatly appreciate any tips or guidance. Thank you very much!

proxy_buffering off; should fix the issue with RPC/MAPI over HTTP

I would prefere to use Nginx... so if this would work it would be great, thanks for your support!

@Edrard
Copy link

Edrard commented May 30, 2023

Thanks, HA

parsing [/usr/local/etc/haproxy/haproxy.cfg:3] : The 'reqadd' directive is not supported anymore since HAProxy 2.1. Use 'http-request add-header' instead.

I tested but your config did genereate an error...

regarding the certs, can I use the certs generated by Nginix?

I am using first version mostly, but for second one, change reqadd X-Forwarded-Proto:\ https
with
http-request set-header X-Forwarded-Proto https

About certs, I think you can use them, but you will have problems in clients, they will spam about security
I am always using Let Encrypt one

I so many times wasted on nginx, and it's not work correctly with active sync

Right now I have few servers with HAProxy and Exchane on backend, and it's no problems at all.

@tomasenskede
Copy link

Thanks, HA
parsing [/usr/local/etc/haproxy/haproxy.cfg:3] : The 'reqadd' directive is not supported anymore since HAProxy 2.1. Use 'http-request add-header' instead.
I tested but your config did genereate an error...
regarding the certs, can I use the certs generated by Nginix?

I am using first version mostly, but for second one, change reqadd X-Forwarded-Proto:\ https with http-request set-header X-Forwarded-Proto https

About certs, I think you can use them, but you will have problems in clients, they will spam about security I am always using Let Encrypt one

I so many times wasted on nginx, and it's not work correctly with active sync

Right now I have few servers with HAProxy and Exchane on backend, and it's no problems at all.

@Edrard, looks like you have the setup I am looking for. Can we have a chat somehow?

@Edrard
Copy link

Edrard commented May 31, 2023

Leave me you telegram, so I can contact with with you

@tomasenskede
Copy link

tomasenskede commented May 31, 2023

Leave me you telegram, so I can contact with with you

thanks for connecting @Edrard!

@MakoWish
Copy link

MakoWish commented May 31, 2023

One other issue I was having was that the certificate chain was not being loaded correctly. Once I tested with SSL Labs' SSL Server Test, and corrected the issues it reported, everything worked fine for me. Here is my working config:

server {
    listen                     443 ssl http2;
    server_name                www.contoso.com;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";

    location / {
        proxy_pass                 https://10.10.10.10;
        proxy_pass_request_headers on;
        proxy_ssl_name             $host;
        proxy_ssl_server_name      on;
        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_set_header           X-Forwarded-Server  $host;
        proxy_set_header           X-Forwarded-Host  $host:$server_port;
        proxy_set_header           Host  $host;
        proxy_buffer_size          512k;
        proxy_buffers              4 512k;
        proxy_busy_buffers_size    512k;
    }
    error_log                /var/log/nginx/my_site.error.log info;
    ssl_certificate          /etc/nginx/certs/server.crt;
    ssl_certificate_key      /etc/nginx/certs/server.key;
    ssl_trusted_certificate  /etc/nginx/certs/ca_certs.crt;
}

@tomasenskede
Copy link

tomasenskede commented May 31, 2023

One other issue I was having was that the certificate chain was not being loaded correctly. Once I tested with SSL Labs' SSL Server Test, and corrected the issues it reported, everything worked fine for me. Here is my working config:

server {
    listen                     443 ssl http2;
    server_name                www.contoso.com;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";

    location / {
        proxy_pass                 https://10.10.10.10;
        proxy_pass_request_headers on;
        proxy_ssl_name             $host;
        proxy_ssl_server_name      on;
        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_set_header           X-Forwarded-Server  $host;
        proxy_set_header           X-Forwarded-Host  $host:$server_port;
        proxy_set_header           Host  $host;
        proxy_buffer_size          512k;
        proxy_buffers              4 512k;
        proxy_busy_buffers_size    512k;
    }
    error_log                /var/log/nginx/my_site.error.log info;
    ssl_certificate          /etc/nginx/certs/server.crt;
    ssl_certificate_key      /etc/nginx/certs/server.key;
    ssl_trusted_certificate  /etc/nginx/certs/ca_certs.crt;
}

Thank for you reply, if I could get Nginx working with Exhange that would be my first choce.

  1. do you have the site (www.contoso.com) setup in the Nginx GUI with SSL cert?
    1.1) if so, can I use the same cert in the config above? (ever do Nginx store cert created with eht gui)
    1.2) if not, hos do you create ssl certs?

@MakoWish
Copy link

I was not aware there is a GUI for Nginx.

I use NameCheap for my DNS, and I purchased my certificate through them. If you want your site/service to be trusted externally (outside your private network), you will need to purchase your own certificate.

@tomasenskede
Copy link

tomasenskede commented May 31, 2023

I was not aware there is a GUI for Nginx.

I use NameCheap for my DNS, and I purchased my certificate through them. If you want your site/service to be trusted externally (outside your private network), you will need to purchase your own certificate.

image

Nginx Proxy Manager offers a user-friendly graphical interface for managing websites and Let's Encrypt certificates, and it performs exceptionally well. I previously relied on GoDaddy's certificates, but now I exclusively utilize Let's Encrypt certificates.

image

@tomasenskede
Copy link

tomasenskede commented May 31, 2023

@MakoWish - thanks a lot!

When I add this to "Custom Nginx Configuration" I got ActiveSync working!!

POST /Microsoft-Server-ActiveSync/default.eas ... 200 - Success!!!

image

But, MAPI/RPC over HTTP results in HTTP 401-error

/autodiscover/autodiscover.xml ... 401
POST /mapi/nspi/ ... 401

Any idea on why this isnt working?

@MakoWish
Copy link

Have you tested your site with https://www.ssllabs.com/ssltest/?

@tomasenskede
Copy link

Have you tested your site with https://www.ssllabs.com/ssltest/?

image

@tomasenskede
Copy link

tomasenskede commented Jun 2, 2023

Have you tested your site with https://www.ssllabs.com/ssltest/?

@MakoWish

This is my nGinx config;
image
image
image

this is my current config... works great with ActiveSync and OWA but NOT with RPC/MAPI over HTTPS

_add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";

location / {
proxy_pass http://192.168.1.4/;
proxy_ssl_name $host;
proxy_ssl_server_name on;
proxy_pass_request_headers on;
proxy_pass_header Date;
proxy_pass_header Server;
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_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header Host $host;
more_set_input_headers 'Authorization: $http_authorization';
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_read_timeout 3600;

}_

@Rikysonic
Copy link

Rikysonic commented Jul 27, 2023

Do not use nginx for Exchange, it's not work correctly, better use haproxy

frontend ft_https
                bind *:443 ssl crt /etc/haproxy/emailcert.pem
                reqadd X-Forwarded-Proto:\ https
                default_backend bk_exchange

                acl ft_owa      hdr(host) -i email.example.com
                use_backend bk_exchange if ft_owa

backend bk_exchange
                acl path_root url_len 1
                acl path_exchange path_beg -i /autodiscover /owa /oab /ews /public /microsoft-server-activesync /rpc /mapi /favicon.ico
                http-request deny unless path_exchange OR path_root
                server exchange 10.0.25.25:443 check ssl verify none

Thank you, this works extremely well, Outlook connects without any issues.
I've added some default values taken from the web, but the rest is basically untouched:

defaults
    mode http

    retries                   3 # Try to connect up to 3 times in case of failure
    timeout connect           5s # 5 seconds max to connect or to stay in queue
    timeout http-keep-alive   1s # 1 second max for the client to post next request
    timeout http-request      15s # 15 seconds max for the client to send a request
    timeout queue             30s # 30 seconds max queued on load balancer
    timeout client            30m
    timeout server            30m

frontend ft_https
    bind *:443 ssl crt /etc/haproxy/server.pem
    http-request add-header X-Forwarded-Proto https
    default_backend bk_exchange

    acl ft_owa      hdr(host) -i email.example.com
    use_backend bk_exchange if ft_owa

backend bk_exchange
    acl path_root url_len 1
    acl path_exchange path_beg -i /autodiscover /owa /oab /ews /public /microsoft-server-activesync /rpc /mapi /favicon.ico
    http-request deny unless path_exchange OR path_root
    server exchange 10.1.1.1:443 check ssl verify none

I'm using docker-compose, so here's the docker-compose.yml:

version: "2"
services:
    haproxy-exch-reverse-proxy:
        image: haproxy:alpine
        container_name: haproxy-exch-reverse-proxy
        volumes:
        - ./outlook-haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
        - ./server.pem:/etc/haproxy/server.pem
        ports:
        - 443:443
        restart: unless-stopped

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