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;
}
@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