Introduction
Setting up a reverse proxy for an on premises Lync 2013 (aka Skype for Business) environment is fairly straightforward but the technical details are not very well documented, and there is very little out there for the excellent (and my favourite) web server and reverse proxy, nginx.
There are plenty of guides that talk about ISS APR, Apache or other products and few outline the required features of the proxy itself, namely HTTP Proxy 1.1 support, the keepalive parameters and proxy buffers.
This guide’s focus is on the reverse proxy component of the Lync 2013 architecture, you need to make sure that all other architecture requirements are met including DNS records. For help with that see Jack Stromberg’s excellent guide.
Without too much fuss, here is the reverse proxy configuration we are using in production with Lync 2013, it runs on Ubuntu 14.04 and nginx 1.8.0 but will work on most standard nginx environments. This configuration enables remote meeting and mobile application (both iOS and Android).
Nginx Configuration (/etc/nginx/sites-enabled/webext.yourdomain.com.conf
)
Change yourdomain.com to your public domain.
# =====================================================
# LYNC 2013 Reverse Proxy
# MW 2015
# =====================================================
upstream lync_backend {
server your-lync-server.DOMAIN.local:4443;
keepalive 180;
}
server {
listen 443;
server_name webext.yourdomain.com lyncdiscover.yourdomain.com dialin.yourdomain.com meet.yourdomain.com;
# SSL settings
ssl on;
# use strong protocols and ciphers with acceptable fallback
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256: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";
ssl_session_cache shared:SSL:10m;
ssl_prefer_server_ciphers on;
# ssl certificate chain and private key
ssl_certificate /etc/ssl/certs/webext.yourdomain.com_BUNDLED.pem;
ssl_certificate_key /etc/ssl/private/webext.yourdomain.com.key;
error_log /var/www/webext.yourdomain.com_error_log warn;
root /var/www/webext.yourdomain.com;
# reverse proxy to Lync with HTTP Proxy 1.1
location / {
# reset connection to 1.1
proxy_http_version 1.1;
proxy_set_header Connection "";
# buffers
proxy_buffering on;
proxy_buffers 128 4k;
# headers
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 it to lync!
proxy_pass https://lync_backend;
proxy_redirect default;
}
}
# redirect port 80 traffic to 443 without passing it to Lync backend
server {
listen 80;
server_name webext.yourdomain.com lyncdiscover.yourdomain.com dialin.yourdomain.com meet.yourdomain.com;
return 301 https://$host$request_uri;
}
Nginx Configuration (/etc/nginx/nginx.conf
)
# =====================================================
# NGINX Config w/ compression and SSL tweaks
# MW 2015
# =====================================================
user www-data;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
worker_rlimit_nofile 8192;
events {
worker_connections 4096;
# Accept as many connections as possible.
multi_accept on;
}
http {
# MIME types.
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Default log and error files.
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Use sendfile() syscall to speed up I/O operations and speed up static file serving.
sendfile on;
# Timeouts.
client_body_timeout 60;
client_header_timeout 60;
keepalive_timeout 10 10;
send_timeout 60;
# Reset lingering timed out connections. Deflect DDoS.
reset_timedout_connection on;
# Body size.
client_max_body_size 10m;
# TCP options.
tcp_nodelay on;
## Optimization of socket handling when using sendfile.
tcp_nopush on;
# Compression.
gzip on;
gzip_buffers 16 8k;
gzip_comp_level 1;
gzip_http_version 1.1;
gzip_min_length 10;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/x-icon application/vnd.ms-fontobject font/opentype application/x-font-ttf;
gzip_vary on;
gzip_proxied any; # Compression for all requests.
gzip_disable msie6;
# Hide the Nginx version number.
server_tokens off;
# SSL Settings
ssl_session_cache shared:SSL:10m;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/dh_param.pem;
# use strong protocols and ciphers with acceptable fallback
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256: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. A better way to revocate server certificates.
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.4.4 8.8.8.8 valid=300s;
resolver_timeout 10s;
# security headers
add_header Strict-Transport-Security max-age=63072000;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
# indexes
index index.html;
# Include all vhosts.
include /etc/nginx/sites-enabled/*;
}
Generate Diffie-Hellman parameters for Forward Secrecy (/etc/nginx/dh_param.pem
)
Execute the following in your terminal:
openssl dhparam -out /etc/nginx/dh_param.pem 2048
Restart nginx
Execute the following in your terminal:
nginx -s reload
Test Lync 2013 Remote Authentication
Navigate to the following in your browser from outside your network (change yourdomain.com to your public domain):
https://webext.yourdomain.com/WebTicket/WebTicketService.svc
Enter your credentials when prompted:
If all is working you should see something like this:
If not, you’ll likely get a HTTP 401. Check that you have “Negotiate” authentication enabled in your IIS “Lync Server External Web Site” (see below).
Enabling IIS Negotiate Authentication
- On your Lync Server, open IIS Manager.
- Click the “Lync Server External Web Site”
- In the main panel, double click the “Authentication” icon.
- Click “Windows Authentication”, then click “Providers…” from the “Actions” panel.
- From the “Available Providers” drop down, select “Negotiate” and click “Add”.
- Move Negotiate to the top of the provider list using the “Move Up” button.
Thoughts?
Please comment below if this worked for you, or if you have some improvements on this configuration and I’ll update this post. I’d love to hear from you if you’re using nginx with Lync 2013!
The post Guide: NGINX Reverse Proxy for Lync 2013 appeared first on Mike Walton's Technical Journal.