dotnet-monitor has been updated in preview4
to require authentication in the default configuration to access the following endpoints:
/processes
/dump/{pid?}
/gcdump/{pid?}
/trace/{pid?}
/logs/{pid?}
The /metrics
endpoint will still be available without authentication on a separately configured metricsUrl
.
To protect the API keys sent over the wire as part of authentication, dotnet-monitor
will also default to requiring that the underlying channel uses HTTPS.
How to configure dotnet-monitor
for authentication?
Step 1: Generate an SSL certificate
To configure dotnet-monitor
to run securely, you will need to generate an SSL certificate with an EKU for server usage. You can either request this certificate from your certificate authority or generate a self-signed certificate.
If you are running on a development machine with the .NET SDK installed, dotnet-monitor
will default to using the ASP.NET Core HTTPS development certificate. If you wish to generate another self-signed certificate for use on another machine you may do so by invoking the dotnet dev-certs
tool.
dotnet dev-certs https -export-path self-signed-certificate.pfx -p <your-password>
Step 2: Pick an authentication scheme
dotnet-monitor
supports both Windows Authentication (Negotiate) and API token-based authentication. Authenticating requests ensure that lower privileged processes aren't allow to use this API to exfiltrate sensitive diagnostic artifacts that you haven't explicitly granted access to.
We recommend using Windows Authentication if you're running dotnet-monitor
as a local development tool on a Windows machine. For all other environments, we recommend using API token authentication.
Windows authentication doesn't require explicit configuration. When available dotnet-monitor
will authorize any user authenticated as the same user that started the dotnet-monitor
process. You can skip the remaining steps if you're using Windows authentication
Step 3: Generate an API token and hashed API token
You need to create a 32-bit cryptographically random secret for use as an API token
$rng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider
$secret = [byte[]]::new(32)
$rng.GetBytes($secret)
$API_TOKEN = [Convert]::ToBase64String($secret)
"Authorization: Bearer $API_TOKEN"
$secretStream = [System.IO.MemoryStream]::new($secret)
$HASHED_TOKEN = (Get-FileHash -Algorithm SHA256 -InputStream $secretStream).Hash
$rng.Dispose()
Write-Output "ApiKeyHash: $HASHED_TOKEN"
Write-Output "ApiKeyHashType: SHA256"
OR
API_TOKEN=`openssl rand -base64 32`
echo "Authorization: MonitorApiKey $API_TOKEN"
HASHED_TOKEN=`$API_TOKEN | base64 -d | sha256sum`
echo "ApiKeyHash: $HASHED_TOKEN"
echo "ApiKeyHashType: SHA256"
OR
>dotnet monitor generatekey
NOTE: The generated API token should be secured at rest. We recommend using a tool such as a password manager to save it.
Step 4: Save these settings
If you're running on Windows, you can save these settings to %USERPROFILE%\.dotnet-monitor\settings.json
. If you're on other operating systems, you can save this file to $XDG_CONFIG_HOME/dotnet-monitor/settings.json
.
NOTE: If $XDG_CONFIG_HOME
isn't defined, dotnet-monitor will fall back to looking at $HOME/.config/dotnet-monitor/settings.json
{
"ApiAuthentication": {
"ApiKeyHash": "<HASHED-TOKEN>",
"ApiKeyHashType": "SHA256"
},
"Kestrel": {
"Certificates": {
"Default":{
"Path": "<path-to-cert.pfx>",
"Password": "<your-cert-password>"
}
}
}
}
Alternatively, you can use environment variables to specify the configuration
DotnetMonitor_ApiAuthentication__ApiKeyHash="<HASHED-TOKEN>"
DotnetMonitor_ApiAuthentication__ApiKeyHashType="SHA256"
DotnetMonitor_Kestrel__Certificates__Default__Password="<your-cert-password"
DotnetMonitor_Kestrel__Certificates__Default__Path="<path-to-cert.pfx>"
NOTE: If you're using environment variables to configure the API Key hash, you will not be able to the API Key without restarting the process
If you're running in Kubernetes, we recommend creating secrets and mounting them into container via a deployment manifest
Creating secrets:
kubectl create secret generic customcert \
--from-file=customcert.pfx=<path-to-certificate> \
--from-literal=pass=<your-cert-password> \
--dry-run=client -o yaml \
| kubectl apply -f -
kubectl create secret generic apikey \
--from-literal=ApiAuthentication__ApiKeyHash=$hash \
--dry-run=client -o yaml \
| kubectl apply -f -
Deployment manifest:
apiVersion: apps/v1
kind: Deployment
metadata:
name: dotnetmonitorsample
labels:
app: dotnetmonitorsample
spec:
replicas: 1
selector:
matchLabels:
app: dotnetmonitorsample
template:
metadata:
labels:
app: dotnetmonitorsample
spec:
volumes:
- name: sharedtmp
emptyDir: {}
- name: apikey
secret:
secretName: apikey
- name: customcert
secret:
secretName: customcert
containers:
- name: dotnetmonitorsample
imagePullPolicy: Always
image: mcr.microsoft.com/dotnet/samples:aspnetapp
resources:
limits:
memory: "256Mi"
cpu: "500m"
volumeMounts:
- name: sharedtmp
mountPath: /tmp
- name: dotnetmonitoragent
env:
- name: ASPNETCORE_Kestrel__Certificates__Default__Password
valueFrom:
secretKeyRef:
name: customcert
key: pass
- name: ASPNETCORE_Kestrel__Certificates__Default__Path
value: /etc/aspnet/customcert/customcert.pfx
image: mcr.microsoft.com/dotnet/nightly/monitor:5.0.0-preview.4
imagePullPolicy: Always
ports:
- containerPort: 52325
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
volumeMounts:
- name: sharedtmp
mountPath: /tmp
- name: customcert
mountPath: /etc/aspnet/customcert
- name: apikey
mountPath: /etc/dotnet-monitor
How to use dotnet-monitor
for authentication?
If running on Windows with Windows authentication, the browser experience will work as it previously did. The browser handle the Windows authentication challenge.
If you using API Token auth, you will need to specify the token via the authorization header
curl.exe -H "Authorization: MonitorApiKey HdFb8OPkE0Dc5hpu0kAxA7hhNguAah9SNUFftlP2Dk0=" https://localhost:52323/processes
OR
curl -H "Authorization: MonitorApiKey HdFb8OPkE0Dc5hpu0kAxA7hhNguAah9SNUFftlP2Dk0=" https://localhost:52323/processes