Lync Server Web Services are published on Internet via Reverse Proxy. In this article I will show how to configure PfSense (free Firewall solution based on Debian OS) to ask as Reverse Proxy for Lync Server 2010 and Lync Server 2013.
Important: This configuration is not a solution that is officially supported by Microsoft.
Author: Drago Totev, Lync MVP
Publication date: April 2014
Product version: Lync Server 2010, Lync Server 2013
As stated in this blog: http://blogs.technet.com/b/server-cloud/archive/2012/09/12/important-changes-to-forefront-product-roadmaps.aspx, a number of Forefront solutions are discontinued from further releases.
A good friend of mine, and Lync enthusiast, Jason Feusner told me a month ago he published Lync Server 2013 Web services with PfSense (https://www.PfSense.org/index.html). Of course, I’ve decided to give it try.
This article will show:
- Basic initial configuration of PFSenese
- Working with Certificates
- Configuring PfSense to work as Reverse Proxy for Lync Server 2010 ad 2013
About Reverse Proxy for Lync
Before we go through the deployment steps, let us talk once again why we need a RP (Reverse Proxy).
As we know, Lync Director and Front End roles host two web sites: Internal and External.
Lync Server Internal Web Site uses ports 80 and 443
…and the Lync Server External Web Site – 8080 and 4443
One very simplified explanation for why two web sites are required – Lync Server must know where the HTTP request comes from. If the request lands on port 443 – it is “internal” i.e. from LAN. If the request is received on 4443 – from Internet. Think of the meeting Simple URL: https://contoso.com/meet/bob/1A2B3C4D. This link is meant for all participants regardless of the network location they are on at the moment of join process. However, there is a difference in the servers side processing and response based on the requesters network location.
If we were to expose the External web site directly to the Internet, then we would need two links – https://contoso.com for internal participants and another – https://contoso.com:4443 for external participants. Confusing, inefficient, and a really terrible idea!
This is where an RP comes into play. When a participant is external (Internet), natively HTTP requests go to port 443, it is then proxyed to the “external” Web services over port 4443. Lync Server is now aware of the current network location of the participant making the meeting join request.
This concept applies to all Web requests. Here is an example that helps to better visualize the different purposes of Internal and External Web sites – how Lync handles “automatic discovery” (In Lync Server, technically Lyncdiscover; in Exchange, Autodiscover – but Lync Server does use the term Autodiscover as you’ll soon see.) internally and externally. Clients will first try to resolve “lyncdiscoverinternal” and if the record is defined in DNS and located by the client, here is typical response:
Note that the internal web site (nawebint.lynclog.com) is returned.
However, from the Internet, the client will fail on “lyncdiscoverinternal” and will attempt to resolve “lyncdiscover”. The DNS record for “lyncdiscover” will resolve to a public IP, and the request will still be made via port 443. The RP will “flip” the port to 4443 and forward to the “external” web site – now the response looks a lot different:
Here, because the client is connecting to the “external” web site, Lync server replied with the FQDN (nawebext.lynclog.com), and the client can definitely reach it from the Internet.
Now that we’ve reviewed the requirements and general inner workings of internal and external Web services for Lync Server – time to configure an RP for the lab using PfSense.
The “.iso” can be downloaded for the official web site: https://www.PfSense.org/download/mirror.php?section=downloads
…where I made my selection and downloaded from the US mirror.
It appears there is an issue with the network adapters when installed on Hyper-V. While I was able to install it after much added effort, it defeats the purpose of a “5 Minute Reverse Proxy”, hence for this example I will use VMPlayer. Of course, VMPlayer is not the best choice for production environments.
The VM configuration for either VMPlayer or Hyper-V is not in scope for this post.
So… first things first – the planning phase.
I will publish a single SE server using the internal IP address 10.255.2.101 and external Web service FQDN of “nawebext.lynclog.com”.
PfSense itself is a firewall and, just like TMG, it does have LAN and WAN interfaces. For LAN, I will use 10.255.2.118 (on the same VLAN where the Lync SE server is) and WAN – 192.168.1.220 (on my DMZ VLAN). Once configured, I will NAT 192.168.1.118 to a public IP address and test.
Once the install completes (I used the default options to install) and the machine is rebooted, we will be asked to define which virtual NIC interface will be used as WAN on PfSense, and which as LAN.
After my selection of interfaces to assign to WAN, LAN and the confirmation, I get this screen:
As we can see here, LAN was provisioned automatically with the default 192.168.1.1, while WAN received IP from DHCP (I have not placed the NIC on the correct VLAN yet, but plan to do so soon).
Now I need to change my LAN IP address to the one I plan to use (10.255.2.118).
I selected option 2 (“Set Interface(s) IP address”):
…and selected 2 again (because I wanted to configure the LAN):
Since I am not using IPv6, I just hit Enter, and of course, I don’t want PfSense to act as the DHCP server, so I replied “n” on the last question.
After DHCP was disabled, I was asked if I want to enable HTTP as a protocol to access the GUI (in addition to HTTPS). I elected not to do so:
Finally, I am ready to access the GUI and proceed with the configuration. Default user – “admin”, default password – “pfsense”.
Some initial configuration tasks are required, and we need to do those first.
Next is the WAN configuration. Here I will use “Static” as Type and enter the DMZ IP address I selected earlier:
At the bottom of the screen, I uncheck “Block RTC1918 Private Networks” for now, since I want to test the configuration from “inside” before NAT’ing the DMZ address to the public address.
This screen just confirms my previous IP address selection. I reviewed, assured it was what I needed, and clicked "Next".
Lastly, I entered the new password I will use to access the webConfigurator from now on. (Yes, really. Change it from the default. Certainly even the most novice hacker will try “admin”, “pfsense”.)
This completed the initial configuration. Congratulations, indeed! Oh, what a relief it is – I never had to “root” and CHMOD and such.
Reverse Proxy configuration.
The first step is to install the necessary package (System -> Packages):
We are now presented with long list of Packages, but the one I am interested in is “squid3”, a mature reverse proxy (which is why we’re here…):
Note the “plus” on the right. We use this icon to “add” in PfSense.
Now, the “Reverse Proxy” service under “Services” is available:
Certificates always have been (sort of) a gray area for many people. While general certificate discussion is outside of the scope of this topic, I will still detail the steps and hope this will help readers understand the process.
Note: One place where many people get confused in regards to certificates and where they are generated is due to the requirement that the private key and public key must be on the server that the certificate is for. What is sent to your public (or, private, internal CA for that matter) CA is the public key. The reason you send it to a public CA is because – in theory – everyone trusts a publicly recognized entity. The public key – in the form of the certificate – is returned to you signed as “We vouch for this site and public key” and re-associated with the private key which is on the machine that requested it.
If the machine it is intended for and the certificate generator (i.e. the CSR) are the same – importing the certificate (public key) will re-associate the two keys. If the CSR was done on another machine, you must import the public key back to the machine on which the CSR was generated. You then must export the certificate and the private key, and then re-import the exported public and private key (along with any root and intermediate CA certificates in the path) to the destination server that will use the certificate for the purposes of encryption, and proving its identity to other servers and clients. Of course, if you’ve worked on a pool of Edge Servers, exporting and importing certificates and the private key is something you’re already aware of.
Complex? Well, let’s say that this is just the Cliff Notes version of the Cliff Notes on certificates, public and private key cryptography.
I used DigiCert as my certificate issuer. The certificate was signed and imported on the same server where the CSR (Certificate Signing Request) was generated.
When I open the certificate and go to Certification Path tab, I see the Certificate Chain:
In this case, the Identity Certificate (friendly name – dcpool_ext) was signed by “DigiCert Secure Server CA” (which is intermediate) and the intermediate was signed by DigiCert (which is the Trusted Root)
My first step is to export the Root certificate from my server store and import it to PfSense.
In MMC, Trusted Root Certificate Authorities, I’ve located DigiCert Global Root CA…
…right click and selected All Tasks -> Export
It is important to select Base-64 encoded X.509 (.cer) on this screen.
Define location and name on the next screen and Finish. Locate the .cer file and open it with text editor. Copy the content and navigate to PfSense, System -> CertManager -> CA’s tab. Click the Add icon on right, give it a meaningful name and paste the text in Certificate Data field. Save, of course.
Because our RP will use the HTTPS protocol, I need to import the Identity certificate which will be present to the clients upon the SSL handshake. This is done in Certificates tab:
When the icon (bottom right) with “+” sign is clicked, we are up to rude awakening – yeah, this is Linux, we need the certificate and key in a different format than what we currently have. Luckily for us, DigiCert took care of this problem with their utility: https://www.digicert.com/util/DigiCertUtil.zip
As I’ve mentioned above, my identity certificate is already present on the server. When the application is run, it will examine the local machine Personal store and show all certificates:
Here I will highlight the certificate I want to export and click “Export Certificate” button. This is where it gets interesting. I have two options – export combined (certificate and private key) in PFX format, or two separate files – Certificate file and Key file. I want the latter, since PfSense wants each one configured in separate steps and selection windows.
Now I have the two elements – certificate and key file:
I will open each one with Notepad, copy the content, paste in the appropriate box and “Save”:
The Identity certificate will be available for selection later when configuring the service.
Reverse Proxy configuration
Finally, the service configuration. Services -> Reverse Proxy -> General.
Here I will leave WAN as the RP interface, enter the DMZ IP address and my external FQDN:
This next section is for the HTTP reverse proxy settings:
Next – the HTTPS section. Here I have some work to do – I will need to put the Intermediate Certificate from the certificate chain of my public certificate and associate my Identity certificate. I will use the procedure described above (Export Root Certificate) to Export, copy and paste the Intermediate in the “Intermediate CA Certificate” box and select the Identity Certificate from the drop down menu.
Save the listener configuration.
Now it is time to define the (web) server (“Web Servers” tab):
A few things to consider here:
“Enable this peer” is self-explanatory
“Peer Alias” is friendly name we will use in Mappings later
“Peer IP” is the IP address of the FE server. If we are publishing EE pool, this IP will be the VIP of the HLB handling the load balancing.
“Peer Port” is the 4443 because we will forward traffic to the External web site as we discussed earlier.
“Peer Protocol” is HTTPS
Save and add new Web Service (this one will be for HTTP traffic):
Next we need to map the Web Service we created earlier:
Tip – the “Group Name” is “Peer Alias” we defined in the previous screen:
Lastly, because PfSense is a Firewall to begin with, we must allow traffic to flow via port 443 inbound. Note that if the PfSense server is behind hardware firewall, an exclusion still is required there as well.
Firewall -> Rules:
Click “+” to add new rule
Save the rule (don’t forget to “Apply Changes” on top) and… time to test.
Success! Last step – I still need to 1:1 NAT public IP to my PfSense (WAN) DMZ IP, configure the external firewall and test in the real world.
Reverse Proxy is an essential part of Lync Server Web Services publishing process. When configured correctly, PfSense can be used to publish multiple External Lync pools web services, Office Web Applications Server, Exchange Client Access Server services and more – with a single IP Address only.
Special thanks to my good friend and colleague Rick Kingslan for the sanity and language check.