question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Announcement: dotnet monitor will require authentication

See original GitHub issue

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-monitorsupports 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

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
shirhatticommented, Mar 30, 2021

would like to have a way to opt-out too.

dotnet monitor collect --no-auth

0reactions
idg10commented, Apr 27, 2021

This seems to be planning to use a non-standard scheme, MonitorApiToken for the Authorization HTTP header. According to the HTTP standard for authentication (RFC7235) the scheme is meant to be one of those registered in IANA’s Hypertext Transfer Protocol (HTTP) Authentication Scheme Registry. (The alternative mechanism you mention, Negotiate, is registered with IANA. So the problem is just with the novel MonitorApiToken you’ve proposed.)

The first obvious question is: why aren’t you just using Bearer? RFC6750 defines this scheme, and the operation of your proposed MonitorApiToken seems to be a reinvention of the existing Bearer token scheme but by another name.

There’s a really good reason for using the existing standard Bearer scheme: bearer tokens have certain risks attached to them. Because there’s no proof of ownership mechanism, it’s really important to ensure they are suitably protected. Since Bearer is a well-defined standard scheme, HTTP infrastructure (proxies, caching, APIs) can be built with a baked-in understanding of the risks, making it possible to impose policies that prevent accidental leaking of data. (E.g., an egress point could detect the use of a Bearer header in an unencrypted request and block it.) But by defining your own non-standard bearer token scheme, you will lose any such protection. This use of a non-standard security scheme introduces security risks, and for no obvious benefit.

Second, if you were to attempt to get IANA to register your new scheme, it would almost certainly be rejected because it violates the third bullet point in RFC7235’s ‘Considerations for New Authentication Schemes’. You are in effect using the token68 production in your header here. This is exactly what Bearer does, but the Bearer scheme is allowed to get away with this because, as that section of RFC7235 says:

The “token68” notation was introduced for compatibility with existing authentication schemes

I.e., Bearer already worked this way, and it’s regrettable, but too late to change, so the current spec makes a special case for it. But as it says:

new schemes ought to use the auth-param syntax instead

Your proposed MonitorApiToken scheme is definitely “new” so it should use the auth-param syntax defined in RFC7235’s Challenge and Response section.

EDIT (by @shirhatti): Created a new issue to track this https://github.com/dotnet/dotnet-monitor/issues/247

Read more comments on GitHub >

github_iconTop Results From Across the Web

dotnet-monitor/documentation/authentication.md at main
Authentication. Authenticated requests to dotnet monitor help protect sensitive diagnostic artifacts from unauthorized users and lower privileged processes.
Read more >
What's new in dotnet monitor - .NET Blog
Requiring authentication is part of the work that's gone into hardening dotnet monitor to make it suitable for deployment in production ...
Read more >
Experimental Dotnet Monitor Tool Now Fully Supported
Security and Hardening: Requiring authentication is part of the work that's gone into hardening dotnet monitor to make it suitable for ...
Read more >
What's New in .NET 7 for Authentication and Authorization
Let's explore the new .NET 7 features for improving and simplifying authentication and authorization support in .NET applications.
Read more >
Configuring dotnet-monitor with Prometheus and Grafana
BTW, I'm using --no-auth just to get rid of any authentication/certificates issues for such a simple demo. Step 3 - Prometheus. Prometheus is...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found