Configuring nginx reverse proxy for Exchange 2010
2016-NOV-16

This will be a quick post that I hope other might find usefully when deploying nginx as a reverse proxy for Exchange 2010 SP3. With my particular setup, we had two reverse proxy servers; one on the DMZ, and the other was on the LAN and firewall rules that only allow them to communicate with each other through standard HTTP/S ports.

Here's quick dirty diagram of the final setup:

Internet -> Firewall -> DMZ -> Reverse Proxy 1 -> Firewall -> Reverse Proxy 2 -> Exchange

nginx conf

Reverse proxy 1

server {
        listen 443 ssl;
        server_name outlookserver.com;
        ssl_certificate /path/to/outlookserver.crt;
        ssl_certificate_key /path/to/outlookserver.key;
        ssl_prefer_server_ciphers On;
        ssl_protocols TLSv1.1 TLSv1.2;
        ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
        ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
        ssl_dhparam /path/to/dhparam.pem;
        ssl_session_cache shared:SSL:10m;
        add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
        add_header X-Content-Type-Options nosniff;
        add_header X-Frame-Options ALLOW;

        location / {
                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;

                # Fix the "It appears that your reverse proxy set up is broken" error.
                proxy_pass https://reverseproxy2;
                proxy_read_timeout 360;

                error_log /var/log/nginx/owa-ssl-error.log;
                access_log /var/log/nginx/owa-ssl-access.log;
    }
}

Reverse proxy 1

server {
        server_name outlookserver.com;
        listen 443;

        ssl on;
        ssl_certificate /path/to/outlookserver.crt;
        ssl_certificate_key /path/to/outlookserver.key;
        ssl_session_timeout 5m;
        location / {
                return 301 https://outlookserver.com/owa;
        }

        proxy_http_version 1.1;
        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;
        proxy_pass_request_headers on;
        more_set_input_headers 'Authorization: $http_authorization';
        proxy_set_header Accept-Encoding "";
        more_set_headers -s 401 'WWW-Authenticate: Basic realm="outlookserver.com"';
        # proxy_request_buffering off;
        proxy_buffering off;
        proxy_set_header Connection "Keep-Alive";

        location ~* ^/owa { proxy_pass https://exchangeserver; }
        location ~* ^/Microsoft-Server-ActiveSync { proxy_pass https://exchangeserver; }
        location ~* ^/ecp { proxy_pass https://exchangeserver; }
        location ~* ^/rpc { proxy_pass https://exchangeserver; }

        error_log /var/log/nginx/owa-ssl-error.log;
        access_log /var/log/nginx/owa-ssl-access.log;
}
READ
PowerShell script to check if computer is online
2016-OCT-26

I wrote this PowerShell function a while back. I might have a better/newer version of this somewhere, if I find it, I'll update this post with it. With that said, this requires the Quest ActiveRoles cmdlets. I don't like what Dell is doing with the Quest cmdlets, but at least you can find version 1.51 download still for free.

<#
    .SYNOPSIS
        Take an IP address or a computer name as input and test to see if that
        computer is valid, and if it's pingable

    .DESCRIPTION
        Takes an input and does some validation on the input

    .EXAMPLE
        Using with an IP address
        Check-Computer 192.168.1.1

    .EXAMPLE
        Using with a computer name
        Check-Computer ott-0001

    .NOTES
        Stephen Lam
#>
function Check-Computer ($ipOrCompName)
{
    #//Add Quest CMDlets as it's needed for this script
    Add-PSSnapin Quest.ActiveRoles.ADManagement -ErrorAction SilentlyContinue

    if($ipOrCompName -ne $null)
    {
        #//Test to see if the $ipOrCompName is a valid IP format
        #//IP is in a valid IP format; it will use Test-Connection CMDlet to see
        #//if that IP is pingable
        if([bool]($ipOrCompName -as [Net.IPAddress])){
            if(Test-Connection -ComputerName $ipOrCompName -Count 1 -Quiet -ErrorAction SilentlyContinue){
                $compName = [System.Net.Dns]::GetHostEntry($ipOrCompName).HostName
            }
            else{
                #//Couldn't find a computer that's base on the IP address
                $compName = $null
            }
        }

        #//Since the input is not in a valid IP format, it will test to see if this is or
        #//a part of a computer name
        else{
            #//Searches the whole AD for computer that starts with $ipOrCompName
            $compTest = Get-QADComputer -Identity $ipOrCompName*

            #//Checks to see if there's more than one computer object that returns from the search
            #//If there is, it will either list all the computer it found and allow the user to
            #//select the computer they want, or if it's just one computer that returns from the
            #//search, it will use that one automatically
            if ($compTest -ne $null){
                #//More than one computer object found with that search criteria
                If($compTest.count -gt 1){
                    $counter = 1
                    Write-Host "Found" $compTest.Count "that matches" $ipOrCompName
                    foreach($obj in $compTest){
                        Write-Host "$counter)" $obj.Name
                        $counter++
                    }
                    $select = Read-Host "Please enter the your selection (eg. 1 for" $compTest[0].Name")"

                    #//Checks to see if the selected computer is pingable/online
                    if(Test-Connection -ComputerName $compTest[$select-1].Name -Count 1 -Quiet){
                        $compName = $compTest[$select-1].Name
                    }
                    else{
                        #//Couldn't ping the computer
                        $compName = $null
                    }
                }

                #//Only one computer object found in the AD that matches the criteria
                else{
                    #//Checks to see if the selected computer is pingable/online
                    if(Test-Connection -ComputerName $compTest.Name -Count 1 -Quiet -ErrorAction SilentlyContinue){
                        $compName = $compTest.Name
                    }
                    else{
                        $compName = $null
                    }
                }
            }

            else{
                $compName = $null
            }
        }
    }
    else{
        #//No computer found base on the IPorCompName
        $compName = $null
    }
    #//Returns the $compName either with a name or $null if it did not find anything
    return $compName
}
READ
First commit to GitHub
2016-OCT-13

So I did my first commit to my GitHub for this theme. I need to read about the licensing regarding Semantic-UI's work and make sure they are properly credited. Either way, I'm glad the initial commit/push is done. I doubt any other PicoCMS user will use this theme beside myself, but it's available now for anybody to clone and start using.

I don't know how active I'll be developing this further, but I'll slowly work on this to my fit my needs, and continue to learn more about front end design work while doing so. I really enjoy learning more about PicoCMS, Twig and Semantic-UI so far, and I feel that the more I learn regarding these things, the more it helps out with my professional life.

READ
Cover page added
2016-OCT-12

I added a cover page for the this blog, to make it look a little more fancy. I'm pretty happy with how it turned out, but it's basically the Semantic-UI's layout example, but I did change some stuff. I added a background, and set the menu borders to none. The background image I used is a super gaussian blurred shot that Tuong and I took while on vacation at Maui.

All to say, I'm quite happy with what I have right now. I have done most of what I set out to do for this theme, but there's a couple of more features I want to add. I'll see if I have time to do it, and if it's worth the effort.

READ
Menu and pagination generation added!
2016-OCT-07

I've been putting more time into this PicoCMS theme, and there's a little bit more functional now. The menu is now auto-generated from .md files with specific YAML header. I've also start using the PicoCMS pagination plugin with this theme, and it's working out well.

There's still a lot of work left; the top menu is something I want to fix, as I find it extremely boring right now. Another thing I want to do is a front page, with something flashy.

This has been a lot of fun, and I'm excited to continue learning more about Twig, Semantic-UI and JQuery.

READ