{"id":13457950,"url":"https://github.com/natemcmaster/LettuceEncrypt","last_synced_at":"2025-03-24T14:32:31.256Z","repository":{"id":37861135,"uuid":"128607600","full_name":"natemcmaster/LettuceEncrypt","owner":"natemcmaster","description":"Free, automatic HTTPS certificate generation for ASP.NET Core web apps","archived":false,"fork":false,"pushed_at":"2024-06-23T02:24:46.000Z","size":644,"stargazers_count":1647,"open_issues_count":10,"forks_count":162,"subscribers_count":43,"default_branch":"main","last_synced_at":"2025-03-20T19:49:19.358Z","etag":null,"topics":["acme","acme-client","aspnetcore","certificate","dotnet-core","https","lets-encrypt"],"latest_commit_sha":null,"homepage":"https://nuget.org/packages/LettuceEncrypt","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/natemcmaster.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-04-08T06:38:39.000Z","updated_at":"2025-03-13T09:19:02.000Z","dependencies_parsed_at":"2023-02-10T08:31:53.060Z","dependency_job_id":"c1a9e10a-4fb3-431f-a30a-c72d0fbfecb8","html_url":"https://github.com/natemcmaster/LettuceEncrypt","commit_stats":{"total_commits":216,"total_committers":14,"mean_commits":"15.428571428571429","dds":0.2777777777777778,"last_synced_commit":"2ca07d26249e9a7bcb4f7671d5fccbf61089c454"},"previous_names":["natemcmaster/letsencrypt"],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/natemcmaster%2FLettuceEncrypt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/natemcmaster%2FLettuceEncrypt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/natemcmaster%2FLettuceEncrypt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/natemcmaster%2FLettuceEncrypt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/natemcmaster","download_url":"https://codeload.github.com/natemcmaster/LettuceEncrypt/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245289725,"owners_count":20591122,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["acme","acme-client","aspnetcore","certificate","dotnet-core","https","lets-encrypt"],"created_at":"2024-07-31T09:00:40.412Z","updated_at":"2025-03-24T14:32:30.854Z","avatar_url":"https://github.com/natemcmaster.png","language":"C#","funding_links":[],"categories":["C\\#","others","C#","C# #"],"sub_categories":[],"readme":"\u003ch1\u003e\n\u003cimg src=\"./src/icon.png\" width=\"42\" height=\"42\"/\u003e\nLettuceEncrypt for ASP.NET Core\n\u003c/h1\u003e\n\n[![Build Status][ci-badge]][ci] [![Code Coverage][codecov-badge]][codecov]\n[![NuGet][nuget-badge] ![NuGet Downloads][nuget-download-badge]][nuget]\n\n[ci]: https://github.com/natemcmaster/LettuceEncrypt/actions?query=workflow%3ACI+branch%3Amain\n[ci-badge]: https://github.com/natemcmaster/LettuceEncrypt/workflows/CI/badge.svg\n[codecov]: https://codecov.io/gh/natemcmaster/LettuceEncrypt\n[codecov-badge]: https://codecov.io/gh/natemcmaster/LettuceEncrypt/branch/main/graph/badge.svg?token=l6uSsHZ8nA\n[nuget]: https://www.nuget.org/packages/LettuceEncrypt/\n[nuget-badge]: https://img.shields.io/nuget/v/LettuceEncrypt.svg?style=flat-square\n[nuget-download-badge]: https://img.shields.io/nuget/dt/LettuceEncrypt?style=flat-square\n[ACME]: https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment\n[Let's Encrypt]: https://letsencrypt.org/\n\nLettuceEncrypt provides API for ASP.NET Core projects to integrate with a certificate authority (CA), such as\n[Let's Encrypt], for free, automatic HTTPS (SSL/TLS) certificates using the [ACME] protocol.\n\nWhen enabled, your web server will **automatically** generate an HTTPS certificate during start up.\nIt then configures Kestrel to use this certificate for all HTTPS traffic.\nSee [usage instructions below](#usage) to get started.\n\nCreated and developed by [@natemcmaster](https://github.com/natemcmaster) with ❤️ from Seattle ☕️.\nThis project was formerly known as \"McMaster.AspNetCore.LetsEncrypt\", but [has been renamed for\ntrademark reasons](https://github.com/natemcmaster/LettuceEncrypt/issues/99). This project is **not an official\noffering** from Let's Encrypt® or ISRG™.\n\nThis project is 100% organic and best served cold with ranch and carrots. 🥬\n\n### Project status\n\nThis project is in maintenance mode. I lost interest in developing features. I will make a patch if there is a security issue. I'll also consider an update if a new .NET major version breaks and the patch fix required is small. Please see https://github.com/natemcmaster/LettuceEncrypt/security/policy if you wish to report a security concern.\n\n## Will this work for me?\n\nThat depends on [which kind of web server you are using](#web-server-scenarios). This library only works with\n[Kestrel](https://docs.microsoft.com/aspnet/core/fundamentals/servers/kestrel), which is the default server\nconfiguration for ASP.NET Core projects. Other servers, such as IIS and HTTP.sys, are not supported.\nFurthermore, this only works when Kestrel is the edge server.\n\nNot sure? [Read \"Web Server Scenarios\" below for more details.](#web-server-scenarios)\n\nUsing :cloud: Azure App Services (aka WebApps)? This library isn't for you, but you can still get free HTTPS certificates.\nSee [\"Securing An Azure App Service with Let's Encrypt\"](https://www.hanselman.com/blog/SecuringAnAzureAppServiceWebsiteUnderSSLInMinutesWithLetsEncrypt.aspx) by Scott Hanselman for more details.\n\n## Usage\n\nInstall this package into your project using NuGet ([see details here][nuget]).\n\nThe primary API usage is to call `IServiceCollection.AddLettuceEncrypt` in the `Startup` class `ConfigureServices` method.\n\n```csharp\nusing Microsoft.Extensions.DependencyInjection;\n\npublic class Startup\n{\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddLettuceEncrypt();\n    }\n}\n```\n\nA few required options should be set, typically via the appsettings.json file.\n\n```jsonc\n// appsettings.json\n{\n    \"LettuceEncrypt\": {\n        // Set this to automatically accept the terms of service of your certificate authority.\n        // If you don't set this in config, you will need to press \"y\" whenever the application starts\n        \"AcceptTermsOfService\": true,\n\n        // You must specify at least one domain name\n        \"DomainNames\": [ \"example.com\", \"www.example.com\" ],\n\n        // You must specify an email address to register with the certificate authority\n        \"EmailAddress\": \"it-admin@example.com\"\n    }\n}\n```\n\n## Additional options\n\n### Kestrel configuration\n\nIf your code is using the `.UseKestrel()` method to configure IP addresses, ports, or HTTPS settings,\nyou will also need to call `UseLettuceEncrypt`. This is required to make Lettuce Encrypt work.\n\n#### Example: ConfigureHttpsDefaults\n\nIf calling `ConfigureHttpsDefaults`, use `UseLettuceEncrypt` like this:\n\n```c#\nwebBuilder.UseKestrel(k =\u003e\n{\n    var appServices = k.ApplicationServices;\n    k.ConfigureHttpsDefaults(h =\u003e\n    {\n        h.ClientCertificateMode = ClientCertificateMode.RequireCertificate;\n        h.UseLettuceEncrypt(appServices);\n    });\n});\n```\n\n#### Example: Listen + UseHttps\nIf using `Listen` + `UseHttps` to manually configure Kestrel's address binding, use `UseLettuceEncrypt` like this:\n\n```c#\nwebBuilder.UseKestrel(k =\u003e\n{\n    var appServices = k.ApplicationServices;\n    k.Listen(\n        IPAddress.Any, 443,\n        o =\u003e o.UseHttps(h =\u003e\n        {\n            h.UseLettuceEncrypt(appServices);\n        }));\n});\n```\n\n### Customizing storage\n\nCertificates are stored to the machine's X.509 store by default. Certificates can be stored in additional\nlocations by using extension methods after calling `AddLettuceEncrypt()` in the `Startup` class.\n\nMultiple storage locations can be configured.\n\n### Save generated certificates and account information to a directory\n\nThis will save and load certificate files (PFX format) using the specified directory.\nIt will also save your certificate authority account key into the same directory.\n\n```c#\nusing LettuceEncrypt;\nusing Microsoft.Extensions.DependencyInjection;\n\npublic void ConfigureServices(IServiceCollection services)\n{\n    services\n        .AddLettuceEncrypt()\n        .PersistDataToDirectory(new DirectoryInfo(\"C:/data/LettuceEncrypt/\"), \"Password123\");\n}\n```\n\n### Save generated certificates to Azure Key Vault\n\nInstall [LettuceEncrypt.Azure](https://nuget.org/packages/LettuceEncrypt.Azure).\nThis will save and load certificate files using an Azure Key Vault.\nIt will also save your certificate authority account key as a secret in the same vault.\n\n```c#\nusing LettuceEncrypt;\nusing Microsoft.Extensions.DependencyInjection;\n\npublic void ConfigureServices(IServiceCollection services)\n{\n    services\n        .AddLettuceEncrypt()\n        .PersistCertificatesToAzureKeyVault();\n}\n```\n\n```jsonc\n// appsettings.json\n{\n    \"LettuceEncrypt\": {\n        \"AzureKeyVault\": {\n            // Required - specify the name of your key vault\n            \"AzureKeyVaultEndpoint\": \"https://myaccount.vault.azure.net/\"\n\n            // Optional - specify the secret name used to store your account info (used for cert rewewals)\n            // If not specified, name defaults to \"le-encrypt-${ACME server URL}\"\n            \"AccountKeySecretName\": \"my-lets-encrypt-account\"\n        }\n    }\n}\n```\n\n### Customizing how the certs are saved and loaded\n\nCreate a class that implements `ICertificateRepository` to customize how to save your certificates.\n\nCreate a class that implements `ICertificateSource` to customize where pre-existing certificates are\nfound when the server starts.\n\n```c#\nusing LettuceEncrypt;\nusing Microsoft.Extensions.DependencyInjection;\n\npublic void ConfigureServices(IServiceCollection services)\n{\n    services.AddLettuceEncrypt();\n    services.AddSingleton\u003cICertificateRepository, MyCertRepo\u003e();\n    services.AddSingleton\u003cICertificateSource, MyCertSource\u003e();\n}\n\nclass MyCertRepo : ICertificateRepository\n{\n    public async Task SaveAsync(X509Certificate2 certificate, CancellationToken cancellationToken)\n    {\n        byte[] certData = certificate.Export(X509ContentType.Pfx, \"optionallySetPfxPassword\");\n        // save this data somehow\n    }\n}\n\nclass MyCertSource : ICertificateSource\n{\n    public async Task\u003cIEnumerable\u003cX509Certificate2\u003e\u003e GetCertificatesAsync(CancellationToken cancellationToken);\n    {\n        // find and return certificate objects. Return an empty enumerable if none are found\n    }\n}\n```\n\n### Customizing saving your account key\n\nYour interactions with the certificate authority are encrypted with a private\nkey which is generated automatically on first-use. To ensure you can renew certificates\nlater using the same account, this account key is saved to disk by default.\nYou can customize where this account information is shared by adding your own implementation\nof `IAccountStore`.\n\n```c#\nusing LettuceEncrypt;\nusing LettuceEncrypt.Accounts;\n\n\npublic void ConfigureServices(IServiceCollection services)\n{\n    services.AddLettuceEncrypt();\n    services.AddSingleton\u003cIAccountStore, MyAccountStore\u003e();\n}\n\n\nclass MyAccountStore: IAccountStore\n{\n    public Task SaveAccountAsync(AccountModel account, CancellationToken cancellationToken)\n    {\n        // save the account object somewhere\n    }\n\n    // add #nullable enable if using c#, or remove the question mark for older versions of C#\n    public Task\u003cAccountModel?\u003e GetAccountAsync(CancellationToken cancellationToken)\n    {\n        // return null if there is no account and one will be created for you\n    }\n}\n```\n\n\n### Changing which challenge types are used\n\nThe ACME protocol supports multiple methods for proving you own a DNS name called \"challenge types\".\nIf you wish to manually select which challenge types are used, set the \"AllowedChallengeTypes\" method.\nThe default value is \"Any\", which means this library will exhaust all supported challenge types before\ngiving up.\n\nCurrent supported values:\n* `Http01` - The HTTP-01 challenge, which uses a well-known URL on the server and a HTTP request/response.\n* `TlsAlpn01` - The TLS-ALPN-01 challenge, which uses an auto-generated, ephemeral certificate in the TLS handshake.\n* `Dns01` - The DNS-01 challenge, which uses TXT record under that domain name.\n* `Any` - _(default)_ - use HTTP-01 and/or TLS-ALPN-01 DNS-01\n\nTip: if you wish to set multiple method types and are use the \"appsettings.json\" approach, provide a comma-seperated list.\n\n\n```json\n{\n    \"LettuceEncrypt\": {\n        \"AllowedChallengeTypes\": \"Http01, TlsAlpn01, Dns01\"\n    }\n}\n```\n\n\n### When using DNS-01\n\nWhen using the DNS-01 challenge a `IDnsChallengeProvider` must be add and replace the `NoOpDnsChallengeProvider`\n\n```c#\npublic class MyDnsChallengeProvider : IDnsChallengeProvider\n{\n    private readonly ISomeExternalDnsClient _client;\n\n    public MyDnsChallengeProvider(ISomeExternalDnsClient client) =\u003e _client = client;\n\n    public Task AddTxtRecordAsync(string domainName, string txt, CancellationToken ct = default)\n    {\n        return _client.AddDnsTxtRecord(domainName, txt, ct);\n    }\n\n    public Task RemoveTxtRecordAsync(string domainName, string txt, CancellationToken ct = default)\n    {\n        return _client.RemoveDnsTxtRecord(domainName, txt, ct);\n    }\n}\n```\n\n## Testing in development\n\nSee the [developer docs](./test/Integration/) for details on how to test in a non-production environment.\n\n## Web Server Scenarios\n\nI recommend also reading [Microsoft's official documentation on hosting and deploying ASP.NET Core](https://docs.microsoft.com/aspnet/core/host-and-deploy/).\n\n### ASP.NET Core with Kestrel\n\n:white_check_mark: supported\n\n![Diagram of Kestrel on the edge with Kestrel](https://i.imgur.com/vhQTgUe.png)\n\nIn this scenario, ASP.NET Core is hosted by the Kestrel server (the default, in-process HTTP server) and that web server exposes its ports directly to the internet. This library will configure Kestrel with an auto-generated certificate.\n\n### ASP.NET Core with IIS\n\n:x: NOT supported\n\n![Diagram of Kestrel on the edge with IIS](https://i.imgur.com/PmrcLkN.png)\n\nIn this scenario, ASP.NET Core is hosted by IIS and that web server exposes its ports directly to the internet. IIS does not support dynamically configuring HTTPS certificates, so this library cannot support this scenario, but you can still configure cert automation using a different tool. See [\"Using Let's Encrypt with IIS On Windows\"](https://weblog.west-wind.com/posts/2016/feb/22/using-lets-encrypt-with-iis-on-windows) for details.\n\nAzure App Service uses this for ASP.NET Core 2.2 and newer, which is why this library cannot support that scenario.. Older versions of ASP.NET Core on Azure App Service run with IIS as the reverse proxy (see below), which is also an unsupported scenario.\n\n\n### ASP.NET Core with Kestrel Behind a TCP Load Balancer (aka SSL pass-thru)\n\n:white_check_mark: supported\n\n![Diagram of TCP Load Balancer](https://i.imgur.com/txqLTv5.png)\n\nIn this scenario, ASP.NET Core is hosted by the Kestrel server (the default, in-process HTTP server) and that web server exposes its ports directly to a local network. A TCP load balancer such as nginx forwards traffic without decrypting it to the host running Kestrel. This library will configure Kestrel with an auto-generated certificate.\n\n### ASP.NET Core with Kestrel Behind a Reverse Proxy\n\n:x: NOT supported\n\n![Diagram of reverse proxy](https://i.imgur.com/LA4jms7.png)\n\nIn this scenario, HTTPS traffic is decrypted by a different web server that is beyond the control of ASP.NET Core. This library cannot support this scenario because HTTPS certificates must be configured by the reverse proxy server.\n\nThis is commonly done by web hosting providers. For example, :cloud: Azure App Services (aka WebApps) often runs older versions of ASP.NET Core in a reverse proxy.\n\nIf you are running the reverse proxy, you can still get free HTTPS certificates, but you'll need to use a different method. [Try Googling this](https://www.google.com/search?q=let%27s%20encrypt%20nginx).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnatemcmaster%2FLettuceEncrypt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnatemcmaster%2FLettuceEncrypt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnatemcmaster%2FLettuceEncrypt/lists"}