Skip to content

Commit 833a6a4

Browse files
ranbelthomasgauvin
authored andcommitted
[ZT] Managed network using Windows IIS (#23549)
* windows IIS TLS server * fix SHA-256 fingerprint * fix spacing * fix link
1 parent c18dbb4 commit 833a6a4

File tree

1 file changed

+94
-78
lines changed

1 file changed

+94
-78
lines changed

src/content/docs/cloudflare-one/connections/connect-devices/warp/configure-warp/managed-networks.mdx

Lines changed: 94 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -57,120 +57,136 @@ If you do not already have a TLS endpoint on your network, you can set one up as
5757

5858
1. Generate a TLS certificate:
5959

60-
```sh
61-
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout example.key -out example.pem -subj "/CN=example.com" -addext "subjectAltName=DNS:example.com"
62-
```
60+
```sh
61+
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout example.key -out example.pem -subj "/CN=example.com" -addext "subjectAltName=DNS:example.com"
62+
```
6363

64-
The command will output a certificate in PEM format and its private key. Store these files in a secure place.
64+
The command will output a certificate in PEM format and its private key. Store these files in a secure place.
6565

66-
:::note
66+
:::note
6767

68-
The WARP client requires certificates to include `CN` and `subjectAltName` metadata. You can use `example.com` or any other domain.
69-
:::
68+
The WARP client requires certificates to include `CN` and `subjectAltName` metadata. You can use `example.com` or any other domain.
69+
:::
7070

71-
2. Next, configure an HTTPS server on your network to use this certificate and key. The examples below demonstrate how to run a barebones HTTPS server that responds to requests with a `200` status code:
71+
2. Configure an HTTPS server on your network to use this certificate and key. The example below demonstrates how to serve the TLS certificate from an nginx container in Docker:
7272

73-
<Details header="nginx in Docker">
73+
a. Create an nginx configuration file called `nginx.conf`:
7474

75-
To serve the TLS certificate from an nginx container in Docker:
75+
```txt
76+
events {
77+
worker_connections 1024;
78+
}
7679
77-
1. Create an nginx configuration file called `nginx.conf`:
80+
http {
81+
server {
82+
listen 443 ssl;
83+
ssl_certificate /certs/example.pem;
84+
ssl_certificate_key /certs/example.key;
85+
location / {
86+
return 200;
87+
}
88+
}
89+
}
90+
```
7891

79-
```txt
80-
events {
81-
worker_connections 1024;
82-
}
92+
If needed, replace `/certs/example.pem` and `/certs/example.key` with the locations of your certificate and key.
8393

84-
http {
85-
server {
86-
listen 443 ssl;
87-
ssl_certificate /certs/example.pem;
88-
ssl_certificate_key /certs/example.key;
89-
location / {
90-
return 200;
91-
}
92-
}
93-
}
94-
```
94+
b. Add the nginx image to your Docker compose file:
9595

96-
If needed, replace `/certs/example.pem` and `/certs/example.key` with the locations of your certificate and key.
96+
```yml
97+
version: "3.3"
98+
services:
99+
nginx:
100+
image: nginx:latest
101+
ports:
102+
- 3333:443
103+
volumes:
104+
- ./nginx.conf:/etc/nginx/nginx.conf:ro
105+
- ./certs:/certs:ro
106+
```
97107

98-
2. Add the nginx image to your Docker compose file:
108+
If needed, replace `./nginx.conf` and `./certs` with the locations of your nginx configuration file and certificate.
99109

100-
```yml
101-
version: "3.3"
102-
services:
103-
nginx:
104-
image: nginx:latest
105-
ports:
106-
- 3333:443
107-
volumes:
108-
- ./nginx.conf:/etc/nginx/nginx.conf:ro
109-
- ./certs:/certs:ro
110-
```
110+
c. Start the server:
111111

112-
If needed, replace `./nginx.conf` and `./certs` with the locations of your nginx configuration file and certificate.
112+
```sh
113+
docker-compose up -d
114+
```
113115

114-
3. Start the server:
116+
3. To test that the TLS server is working, run a curl command from the end user's device:
115117

116-
```sh
117-
docker-compose up -d
118-
```
118+
```sh
119+
curl --verbose --insecure https://<private-server-IP>:3333/
120+
```
119121

120-
</Details>
122+
You need to pass the `--insecure` option because we are using a self-signed certificate. If the device is connected to the network, the request should return a `200` status code.
121123

122-
<Details header="Python">
124+
<Details header="Windows IIS">
123125

124-
:::caution
126+
To create a TLS endpoint using Windows Internet Information Services (IIS) Manager:
125127

126-
This Python script is intended for a quick proof of concept (PoC) and should not be used in production environments.
127-
:::
128+
1. Run Powershell as administrator.
128129

129-
To serve the TLS certificate using Python:
130+
2. Generate a self-signed certificate:
130131

131-
1. Create a Python 3 script called `myserver.py`:
132+
```powershell
133+
New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName "office-name.example.internal" -FriendlyName "Cloudflare Managed Network Certificate" -NotAfter (Get-Date).AddYears(10)
134+
```
132135

133-
```txt
134-
import ssl, http.server
136+
```powershell output
137+
PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\My
135138
136-
class BasicHandler(http.server.BaseHTTPRequestHandler):
137-
def do_GET(self):
138-
self.send_response(200)
139-
self.send_header('Content-type', 'text/html')
140-
self.end_headers()
141-
self.wfile.write(b'OK')
142-
return
139+
Thumbprint Subject
140+
---------- -------
141+
0660C4FCD15F69C49BD080FEEA4136B3D302B41B CN=office-name.example.internal
142+
```
143143

144-
server = http.server.ThreadingHTTPServer(('0.0.0.0', 3333), BasicHandler)
145-
sslcontext = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
146-
sslcontext.load_cert_chain(certfile='./example.pem', keyfile='./example.key')
147-
server.socket = sslcontext.wrap_socket(server.socket, server_side=True)
148-
server.serve_forever()
149-
```
144+
3. Extract the certificate's SHA-256 fingerprint:
150145

151-
2. Run the script:
146+
```powershell
147+
[System.BitConverter]::ToString([System.Security.Cryptography.SHA256]::Create().ComputeHash((Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.FriendlyName -eq "Cloudflare Managed Network Certificate" }).RawData)) -replace "-", ""
148+
```
152149

153-
```sh
154-
python3 myserver.py
155-
```
150+
```powershell output
151+
DD4F4806C57A5BBAF1AA5B080F0541DA75DB468D0A1FE731310149500CCD8662
152+
```
156153

157-
</Details>
154+
You will need the SHA-256 fingerprint to [configure the managed network in Zero Trust](#3-add-managed-network-to-zero-trust). Do not use the default SHA-1 thumbprint generated by the `New-SelfSignedCertificate` command.
158155

159-
3. To test that the server is working, run a curl command from the end user's device:
156+
4. Open IIS Manager.
160157

161-
```sh
162-
curl --verbose --insecure https://<private-server-IP>:3333/
163-
```
158+
5. In the **Connections** pane, right-click the **Sites** node and select **Add Website**.
159+
160+
6. In **Site name**, enter any name for the TLS server (for example, `Managed Network Server`).
164161

165-
You need to pass the `insecure` option because we are using a self-signed certificate. If the device is connected to the network, the request should return a `200` status code.
162+
7. In **Physical path**, enter any directory that contains a `.htm` or `html` file, such as `C:\inetpub\wwwroot`. Cloudflare does not validate the content within the directory.
163+
164+
8. Under **Binding**, configure the following fields:
165+
- **Type**: _https_
166+
- **IP address**: _All Unassigned_
167+
- **Port**: `443`
168+
- **Host name**: Enter the certificate's Common Name (CN). The CN of our example certificate is `office-name.example.internal`.
169+
- **Require Server Name Indication**: Enabled
170+
- **SSL certificate**: Select the name of your TLS certificate. Our example certificate is called `Cloudflare Managed Network Certificate`.
171+
172+
9. To test that the TLS server is working, run a curl command from the end user's device:
173+
174+
```sh
175+
curl --verbose --insecure --resolve office-name.example.internal:443:<private-server-IP> https://office-name.example.internal
176+
```
177+
178+
You need to pass the `--insecure` option because we are using a self-signed certificate. The `--resolve` option allows you to connect to the server's private IP but also pass the hostname to the server for SNI and certificate validation. If the device is connected to the network, the request should return your directory's default homepage (`C:\inetpub\wwwroot\iisstart.htm`).
179+
</Details>
166180

167181
### Supported cipher suites
168182

169183
The WARP client establishes a TLS connection using [Rustls](https://github.com/rustls/rustls). Make sure your TLS endpoint accepts one of the [cipher suites supported by Rustls](https://docs.rs/rustls/0.21.10/src/rustls/suites.rs.html#125-143).
170184

171185
## 2. Extract the SHA-256 fingerprint
172186

173-
<Tabs> <TabItem label="local certificate">
187+
The SHA-256 fingerprint is only required if your TLS endpoint uses a self-signed certificate.
188+
189+
<Tabs> <TabItem label="Local certificate">
174190

175191
To obtain the SHA-256 fingerprint of a local certificate:
176192

@@ -184,7 +200,7 @@ The output will look something like:
184200
SHA256 Fingerprint=DD4F4806C57A5BBAF1AA5B080F0541DA75DB468D0A1FE731310149500CCD8662
185201
```
186202

187-
</TabItem> <TabItem label="remote server">
203+
</TabItem> <TabItem label="Remote server">
188204

189205
To obtain the SHA-256 fingerprint of a remote server:
190206

0 commit comments

Comments
 (0)