Exchange Extended Protection and HAProxy

A reader, who wishes to remain anonymous, has kindly sent me his scripts and configuration for Let's Encrypt, HAProxy and Exchange 2019 in conjunction with Extended Protection so that I can publish them here. First of all, I would like to thank you very much for this, because I think this configuration (HAProxy as reverse proxy for Exchange, certificates via Let's Encrypt) should be more common.

For Windows Extended Protection to work, the same certificates must be used on all Exchange servers, load balancers and reverse proxies. It is not enough for the certificates to contain the same DNS names; they must be the same certificate. So if you use a reverse proxy such as HAProxy and automatically request and configure a certificate there via Let's Encrypt, you must also use this certificate for the Exchange servers.

The friendly reader has created several small scripts for this purpose. The first script is a customized configuration for Certbot. Certbot uses it to renew the certificate at 4:00 am. The script or configuration is saved in the file /etc/systemd/system/certbot.timer.d/override.conf:

1
2
3
4

The next script under /etc/letsencrypt/renewal-hooks/deploy/restart_services ensures that a script called copy_cert.sh is called, which converts the Let's Encrypt certificate into PKCS12 format and saves it on a share:

1
2
3
4
5
6
7
8
;;

The script /var/local/ExchangeCert/copy_cert.sh converts the certificate into the PKCS12 format (PFX file) and copies it to a share so that it can later be imported on the Exchange servers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#

The access data for the share is saved in the file /var/local/ExchangeCert/smbcredentials. This file has the following content:

1
2
3

A PowerShell script is used on the Exchange servers, which imports the certificate from the share into the Exchange server. This script is executed by a scheduled task every day after 04:00:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#
=
=
=
=
=
{
()
= ()
=
}
=
(
=
=
(
=
}
} {
=
}
() {
`
| {
$_ `
(
$_
$_
$_
)
} `
| `
=
( )
{
}
{
($( 0)) ( )
}
{
}
{
= $_ } | 1
}
{
}
|
{
$_ $_ } |
}
{
}
}

I have not recreated the script or configuration myself. However, the configuration and the scripts look conclusive to me. Last but not least, the friendly reader also sent me his HAProxy configuration:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#
#
#
#

This scenario can therefore be replicated quite easily. The scripts still need to be adapted a little, for example access data, paths and IPs, but this should not be a problem. I will try out these scripts in a quiet minute.

Exchange Extended Protection and HAProxy

18 thoughts on “Exchange Extended Protection und HAProxy”

  1. It works almost fine, only ExchangeMAPI is not working for me. It constantly ask for user and password when connecting via Outlook through /mapi. OWA is working fine, activesync is working fine.

    Reply
  2. Hi, habe mich eingelesen und getestet…nur kommt ein Problem, das Zertifikat wird importiert, ist aber nur in der MMC-Konsole sichtbar und nicht im Admin-Center und auch nicht per Get-ExchangeCertificate zu sehen. Hat da jemand eine Idee ?

    Reply
  3. Leider ist die Anleitung auf meiner OpenSense FW mit HaProxy und LetsEncrypt Plugin nicht umsetzbar.
    Weder die genannten Pfade noch die Dateien existieren, auch eine Volltextsuche brachte keine Licht ins dunkel.
    Hat das schon jemand auf OpenSense/pfSense umgesetzt?

    Reply
    • Falls das Thema noch aktuell ist.
      Ich habe aktuell die gleiche Situation.
      Hier meine Lösung:
      Im opnSense unter Services->ACME Client->Automations einen Eintrag erstellen und „Upload certificate via SFTP“ auswählen.
      (auf dem Exchange entsprechend den openssl-server aktivieren, einen Nutzer einrichten, Ordner anlegen und openSSL entsprechend konfigurieren

      Im Gegensatz zu der hier vorgestellten Lösung würde ich das Importieren der Zertifikats nicht über die Uhrzeit regeln sondern einen Filesystem-Watcher installieren, der bei Änderung des Zertifikats den Import triggert.

      Reply
  4. Interessante Lösung, danke fürs Teilen (und an den Autor ).

    Beim Überfliegen fiel mir allerdings eine Kleinigkeit auf: in Zeile 40 des Powershell-Scripts sollte $ShouldImport doch eher auf false stehen, oder nicht? So wie es aktuell eingestellt ist wird (wenn ich den Code richtig lese) der Timestamp-Check quasi ausgehebelt und das Zertifikat jedes Mal ausgetauscht wenn das Script läuft.

    Reply
    • Nein, der Abschnitt wird ausgeführt, wenn die Marker-Datei noch nicht existiert, also bei der allerersten Ausführung. Da hätte der Kommentar besser formuliert sein, bzw. vor der folgenden if-Abfrage stehen können, um es deutlicher zu machen.

      Reply
  5. hallo

    ist es ok dass in if , beide werte $ShouldImport auf True ??

    if ($filePFX.LastWriteTime -gt $fileTimestamp.LastWriteTime) {
    WriteLog „Aktuelles Zertifikat ist neuer als der letzte Import“
    $ShouldImport = $true
    }
    } else {
    $ShouldImport = $true
    }

    Reply
  6. Genial, das Du und in diesem Fall ein anonymer Kollege uns teilhaben lässt an seiner Arbeit und KnowHow.

    1000*Danke dafür.

    Reply
  7. Sehr schön,
    und danke auch von mir an den Leser!
    ich mach diese Schritte seit einer Weile jeden Monat manuell, weil ich nicht die Zeit finde das zu scripten.
    ich werde es morgen mal bei mir einbauen.
    Ich frage mich allerdings, wieso HAProxy als reverse Proxy benutzt wird und nicht zum Beispiel nginx. da kann man doch gleich Pfade sperren oder nur auf bestimmte Clients freischalten. Zum beispiel owa nur für bestimmte Smartphones mit bestimmten User Logins….

    Reply
    • Hallo Christop
      Ich nutze den HAproxy schon länger als PlugIn auf der pfSense

      >da kann man doch gleich Pfade sperren oder
      Ich denke, HAproxy kann auch mir Pfaden umgehen – oder täusche ich mich da ?

      > nur auf bestimmte Clients freischalten. Zum beispiel owa nur für bestimmte Smartphones mit bestimmten User Logins….
      WIe muss ich mir das vorstelle ? Wie muss ich mir das vorstellen ?
      Danke und Grüße, Rolf

      Reply
    • Dachte mir, eine Proxy-Software wäre besser als ein Webserver für einen Proxy ;-)

      Hatte mit nginx bisher nicht viel zu tun und die Anleitungen, auf denen das basiert, haben halt HAProxy verwendet. Also eigentlich kein konkreter Grund, HAProxy zu verwenden, bzw. bisher keine Notwendigkeit für nginx gehabt.

      Falls Du das mit nginx umsetzen solltest, würde mich Deine Konfig aber auch interessieren.

      Reply
      • Viel Spaß mit Nginx und Ex2019 CU17+

        Ab dann muss entweder der Exchange so auf forced basic-auth umgestellt werden, oder die commercial license von nginx.

        Reply
        • wegen kerberos, welches der gratis nginx nicht kann, oder? ntlm geht auch nicht? geht kerberos mit haproxy?

Leave a Comment