Skip to content

Instantly share code, notes, and snippets.

@boutzamat
Forked from crypt0rr/exchange.conf
Created October 16, 2023 10:34
Show Gist options
  • Save boutzamat/356df9bb6f4351528110363af54a4ee6 to your computer and use it in GitHub Desktop.
Save boutzamat/356df9bb6f4351528110363af54a4ee6 to your computer and use it in GitHub Desktop.
Configuration for Microsoft Exchange Server (2010 / 2013 / 2016) behind a (free) nginx reverse proxy. This config allows things like Microsoft ActiveSync.
server {
listen 80;
server_name mail.example.com;
return 301 https://mail.example.com;
}
server {
listen 443 ssl http2;
server_name mail.example.com autodiscover.example.com;
location / {
return 301 https://mail.example.com/owa;
}
# Alllowed endpoints (use DNS or IP for target server)
location ~* ^/owa { proxy_pass https://mail.example.com; }
location ~* ^/Autodiscover { proxy_pass https://mail.example.com; }
location ~* ^/Microsoft-Server-ActiveSync { proxy_pass https://mail.example.com; }
location ~* ^/ecp { proxy_pass https://mail.example.com; }
location ~* ^/mapi { proxy_pass https://mail.example.com; }
location ~* ^/EWS { proxy_pass https://mail.example.com; }
# Proxy options
proxy_pass_request_headers on;
proxy_read_timeout 360s;
proxy_pass_header Date;
proxy_pass_header Server;
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 Accept-Encoding "";
proxy_set_header Connection "Keep-Alive";
proxy_buffering off;
# Hiding headers to prevent information disclosure
proxy_hide_header X-FEServer;
proxy_hide_header X-ASPNET-Version;
proxy_hide_header x-calculatedbetarget;
proxy_hide_header x-beserver;
proxy_hide_header x-diaginfo;
proxy_hide_header x-owa-minimumsupportedowsversion;
proxy_hide_header x-owa-owsversion;
proxy_hide_header x-owa-diagnosticsinfo;
proxy_hide_header x-owa-version;
# Max filesize that can be used (for example attachments)
client_max_body_size 10M;
# Authentication for Outlook against /mapi
more_set_headers -s 401 'WWW-Authenticate: Basic realm="mail.example.com"';
# SSL certificate (LetsEncrypt based)
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_session_timeout 5m;
# Securityheaders
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Content-Security-Policy "frame-ancestors 'self' https://mail.example.com; block-all-mixed-content; upgrade-insecure-requests";
add_header Feature-Policy "microphone 'none'; geolocation 'none'";
add_header Expect-CT "max-age=0";
add_header Referrer-Policy "no-referrer";
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
# Log files
error_log /var/log/nginx/owa-ssl-error.log;
access_log /var/log/nginx/owa-ssl-access.log;
}
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
# Basic Settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
# Server header replacement (requires: nginx-extras)
more_set_headers 'Server: ';
include /etc/nginx/mime.types;
default_type application/octet-stream;
# SSL Settings
ssl_protocols TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
ssl_ciphers TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:EECDH+CHACHA20:ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:!aNULL:!eNULL:!LOW:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS;
# Logging Settings
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Gzip Settings
gzip off;
# Virtual Host Configs
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment