Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Roadmap? What should we do next? #29

Closed
natemcmaster opened this issue Dec 8, 2019 · 26 comments
Closed

Roadmap? What should we do next? #29

natemcmaster opened this issue Dec 8, 2019 · 26 comments
Labels

Comments

@natemcmaster
Copy link
Owner

I don't know where to go next with this project and need your input. What should come next? I started this project in April 2018. This project went dormant for some time when I was overloaded at work. I nearly killed it completely, but Let's Encrypt support was one of the top up-voted feature requests for ASP.NET Core and I received several emails and tweets requesting that I continue this project. So, I revived the project 3 months ago and have released 2 versions. Since then, I haven't heard much from users.

One option I am considering is cancelling this project altogether in favor of an alternative. Shortly after the initial release of this project to NuGet.org, I learned about a similar implementation: https://github.com/ffMathy/FluffySpoon.AspNet.LetsEncrypt. It looks like it started in Oct. 2018, but it has more releases and downloads on NuGet.org. The project appears to have fewer GitHub users than this one...guessing based on stars (70 vs 342) and watchers (8 vs 28). It also appears to have more features than this one, including some requested in this project's issue tracker. Should we cancel this project in favor of FluffySpoon? (@ffMathy - I would like your opinion on this, too).

Also, in general, I'm interested in knowing about who is using this. If you do, can you post a comment to this thread? I'd like to know:

  1. Are you using this project in production?
  2. Do you want feature enhancements? Or is it good enough as-is?

Thanks,
Nate

@qumeta
Copy link

qumeta commented Dec 8, 2019

ths @natemcmaster , Our site is using it and it looks good right now.

@natemcmaster natemcmaster pinned this issue Dec 8, 2019
@natemcmaster
Copy link
Owner Author

natemcmaster commented Dec 8, 2019

Glad to hear that, @qumeta! How are you handling certificate renewals? The most upvoted feature right now is automating cert renewals: #11

@qumeta
Copy link

qumeta commented Dec 8, 2019

Currently we handle it manually.

@pablopioli
Copy link

When your project was dormant I started my own fork based on your code. It´s clunky but it works.
https://github.com/pablopioli/letsencrypt-middleware

I have always seen the make endless competing solutions a waste of effort. There is a lot of examples in the Linux world.

The other problem is the lack of discovery, lots of small implementations will be harder to find to a newbie.

But that`s just my point of view, wich can be wrong. I would also like to hear @ffMathy opinion on his project, I just found it and I like it a lot. Will try to see if I can help with some of the issues reported.

@bordenit
Copy link

bordenit commented Dec 8, 2019 via email

@ffMathy
Copy link

ffMathy commented Dec 8, 2019

@natemcmaster I'm always open to cancel fluffyspoon in favor of this one, or vice versa. You can get full commit access to fluffyspoon too if you wish.

I'm willing to collaborate on what's best for the community!

@natemcmaster
Copy link
Owner Author

Thanks everyone for your replies! I appreciate your comments about what we could do next. Let me address what has been said so far:

@pablopioli: I have always seen the make endless competing solutions a waste of effort. There is a lot of examples in the Linux world.

Yes, I agree it seems to be a waste to have multiple, nearly identical solutions for the same problem. Especially in open-source where we are volunteering our efforts, it seems wise to consolidate effort. That's what I'm hoping to accomplish :)

@bordenit: I think it’s a good project. I looked at it briefly and a container example/tutorial would be great.

Great suggestion! A while ago I started creating a demo using Azure Containers Instances, but found Azure woefully overcomplicated (and yet somehow also missing crucial features). I think I'll take your suggestion and try Digital Ocean instead. It's been a while since I used DO, but I recall it being easy-as-pie to use.

@ffMathy: I'm always open to cancel fluffyspoon in favor of this one, or vice versa. You can get full commit access to fluffyspoon too if you wish. I'm willing to collaborate on what's best for the community!

Thanks for the gracious offer, @ffMathy. I am also trying to seek what is best for the community! I think what would be helpful for me to make a decision here is to have a more in-depth comparison of our projects. I'm going to read your code and will post my findings soon.

@natemcmaster
Copy link
Owner Author

Ok everyone, here is my detailed comparison of the two projects. I am not providing a conclusion here, just the data. I am interested in hearing what you think.

Usage comparison (code)

(Ignoring the add the nuget package step)

mcmaster

  1. Add settings to appsettings.json
{
    "LetsEncrypt": {
        "AcceptTermsOfService": true,
        "DomainNames": [ "example.com", "www.example.com" ],
        "EmailAddress": "it-admin@example.com"
    }
}
  1. Update Startup.ConfigureServices
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddLetsEncrypt();

 	// ... etc ...
    }
}

fluffyspoon

  1. Update Program.CreateWebHostBuilder
public class Program
{
	public const string DomainToUse = "example.com";

	public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
		WebHost.CreateDefaultBuilder(args)
			.UseKestrel(kestrelOptions =>
			{
				kestrelOptions.ConfigureHttpsDefaults(httpsOptions =>
				{
					httpsOptions.ServerCertificateSelector = (c, s) => LetsEncryptRenewalService.Certificate;
				});
			})
			.UseUrls(
				"http://" + DomainToUse,
				"https://" + DomainToUse)
			.UseStartup<Startup>();
}
  1. Update Startup.ConfigureServices and Startup.Configure
public class Startup
{
	public void ConfigureServices(IServiceCollection services)
	{
		services.AddFluffySpoonLetsEncryptRenewalService(new LetsEncryptOptions()
		{
			Email = "some-email@github.com",
			Domains = new[] { Program.DomainToUse },
			TimeUntilExpiryBeforeRenewal = TimeSpan.FromDays(30),
			CertificateSigningRequest = new CsrInfo()
			{
				CountryName = "CountryNameStuff",
				Locality = "LocalityStuff",
				Organization = "OrganizationStuff",
				OrganizationUnit = "OrganizationUnitStuff",
				State = "StateStuff"
			}
		});

		services.AddFluffySpoonLetsEncryptFileCertificatePersistence();
		services.AddFluffySpoonLetsEncryptFileChallengePersistence();

 		// ... etc ...
	}

	public void Configure(IApplicationBuilder app)
	{
		app.UseFluffySpoonLetsEncryptChallengeApprovalMiddleware();
 		// ... etc ...
	}
}

In-depth comparison

Feature fluffyspoon mcmaster
ASP.NET Core versions supported 2.2+ 2.1+
Auto generate and validate certificates with Let's Encrypt
Auto-renew when certificates are expiring
Persists certificates to machine certificate store
Persists certificates to Redis
Persists certificates to EF Core
Persists certificates to file system ✅* (unreleased)
API to customize certificate persistence ✅* (unreleased)
API to customize persistence of Let's Encrypt account key
Specify algorithm for generating private key
Customize the CSR
**Let's Encrypt doesn't support EV or OV certs, so I'm not sure there is much value in this API
Support wildcard domains ❌ * (was implemented and then removed)
Config binding (i.e. configure via appsettings.json)
Support multiple domain names ✅ (via SAN) ✅ (via SAN or different certs)
Support Azure app service SSL binding
Uses ASP.NET developer cert for localhost requests
Public CI/CD and PR test validation
Dependency on https://github.com/fszlin/certes/ Certes exposed in API Certes dependencies is hidden as internal implementation detail
Assembly strong named
Public API has XML documentation some all
Package is authenticode signed
License MIT Apache 2.0

Recommendations for mcmaster, if adopted

Recommendations for fluffyspoon, if adopted

@Tratcher
Copy link
Contributor

ASP.NET Core versions supported 2.2+

Recommendations for fluffyspoon, if adopted

Note ASP.NET Core 2.2 has reached end-of-life. Fluffyspoon should either add support for the 2.1 LTS version or move forward to 3.1 LTS.

@ffMathy
Copy link

ffMathy commented Dec 19, 2019

Strong naming is only needed for .NET Framework. It is redundant for .NET Core.

https://docs.microsoft.com/en-us/dotnet/standard/library-guidance/strong-naming

@ffMathy
Copy link

ffMathy commented Dec 19, 2019

Also @natemcmaster does this library only support renewing, and not necessarily updating the certificate of the server?

Of it does support it, how does it do it? That's what that init code in fluffy spoon is for. If you don't need to apply the certificate, you don't need the init code.

@natemcmaster
Copy link
Owner Author

Re: strong naming. If you read further in the document you shared, it says:

You should strong name your open-source .NET libraries.
https://docs.microsoft.com/en-us/dotnet/standard/library-guidance/strong-naming#create-strong-named-net-libraries

Sure, strong-name signing may not have as many benefits on .NET Core as it did on .NET Framework, but what's the harm ensuring that most people can use your library? I still strong name all of my open-source libraries so anyone out there using strong-naming signing in their code can still use my libraries.

does this library only support renewing, and not necessarily updating the certificate of the server?
Of it does support it, how does it do it?

This library is using the same Kestrel API that fluffyspoon uses to support dynamically rotating certificates. In fluffyspoon, the API usage is something prescribed for users to write in their program.cs file (https://github.com/ffMathy/FluffySpoon.AspNet.LetsEncrypt#configure-kestrel-to-look-for-the-certificate). In this library, that configuration is done automatically through DI. https://github.com/natemcmaster/LetsEncrypt/blob/dffce14ee404bf803b344784337e347d965af502/src/LetsEncrypt/Internal/KestrelOptionsSetup.cs#L10-L26

@ffMathy
Copy link

ffMathy commented Dec 19, 2019

Aha! I didn't know of that particular DI feature. I'll be sure to incorporate that as well.

You are right, there is no harm. I think I am just heavily biased away from strong naming, since I've had all kinds of issues with it in the past and also past workplaces, but of course that shouldn't force everyone else to abandon it as well.

@ffMathy
Copy link

ffMathy commented Dec 19, 2019

A few more questions.

  • By "Document public API" - what do you mean?
  • And what do you mean by simplifying the API and making fewer calls?

One thing I can become worried about after looking at the comparison, is that the API surface should remain simple for the consumer of the API. I fear that adding a lot of features makes it harder to use.

My package was originally designed as a TL;DR solution.

@natemcmaster
Copy link
Owner Author

Good questions! These are some things I try to do on all my class library projects because I think it helps the end user use the library.

Document public API

Add the /// <summary> doc blocks on all public classes, interfaces, enums, etc. and bundle these in the NuGet package so the API explanation lights up in Visual Studio Intellisense. This can be done by adding this to your .csproj files: https://github.com/natemcmaster/LetsEncrypt/blob/dffce14ee404bf803b344784337e347d965af502/src/LetsEncrypt/McMaster.AspNetCore.LetsEncrypt.csproj#L5
Also consider adding a description, tags, and other metadata to the NuGet package so improve its search rank and discoverability. Here are some properties I've set on my project: https://github.com/natemcmaster/LetsEncrypt/blob/dffce14ee404bf803b344784337e347d965af502/Directory.Build.props

what do you mean by simplifying the API and making fewer calls?

Just a friendly suggestion. I think Fluffyspoon can reduce the setup code. The amount of setup code required is by no means overwhelming, but I'm always in favor of reducing boilerplate code. Fluffyspoon could do a several things automatically via DI, like adding middleware (eliminates the UseFluffySpoonLetsEncryptChallengeApprovalMiddleware call) and configure Kestrel (eliminates UseKestrel.ConfigureHttpsDefaults). You might also consider setting defaults for common use cases, like picking a default persistence strategy to eliminate both AddFluffySpoonLetsEncryptFileCertificatePersistence and AddFluffySpoonLetsEncryptMemoryChallengePersistence API calls, and provide options for users to override if they want a non-default strategy.

@natemcmaster
Copy link
Owner Author

But I digress. My take away from the analysis above is that I see more overlap between our projects than differences.

So, here's my thinking. I see one of two options for moving forward.

  1. Deprecate this library, and provide a migration guide for users of this library to adopt fluffyspoon. I have some changes I'd like to see in fluffyspoon first. I think they are mostly about surface and polish. The core of flufyspoon is well done. Here's a list: https://gist.github.com/natemcmaster/618d699a9fcce37d0d953a7e8402503e. Of course, we can discuss each item in more detail, and I'm willing to make pull requests to implement lots of this. If this list overall looks okay, then I can create issues on the fluffyspoon github repo for further conversation.
  2. If option 1 is not agreeable to you, @ffMathy, then I would continue this project, add a few features as mentioned above, invite contributors to add other features that aren't as important to me, but if no one else steps up to add features, this library would enter the "stable, maintained, but not under active development" phase.

Please let me know what you think. I have a preference for option 1 as I think it's best for the community, but I realize this would be asking @ffMathy to take on more ownership. Maintaining my open-source projects has taken more time over the last 5 years than I thought it would. There were more questions and feature requests to respond to than I estimated, fewer people willing to contribute than I hoped for, and there appears to be no end in sight. So, @ffMathy, if you're willing to take on the users of this library, let me know. But if not, that's understandable.

@natemcmaster
Copy link
Owner Author

Hey all, hopefully you had a nice holiday break. Any thoughts on my last comment?

@surfcode
Copy link

surfcode commented Jan 5, 2020

Hey Nate and Mathias, thank you guys for your continued commitment. I just read through the thread (thanks for the detailed comparison!) and through your proposals for fluffyspoon.

I chose your library over fluffyspoons because it is the most elegant solution of the two. Even though fluffyspoons library works equally well, it bloats the code more. In comparison your library is more clean both on the surface (naming conventions, code required, LOC, ...) as well as on the documentation side.

I have a strong preference to this style of code as it adds up to a more readable code base which makes it easier to reason about.

As for your last comment: if Mathias gets the mindset here then I think it is possible to transfer to fluffyspoon. Prerequisites are your proposals and full commit access to fluffyspoon for yourself.
On the other hand, reading up a bit, Mathias said that he is willing to collaborate on what's best for the community so if option 1 does not work then the other way around hopefully works. I am sure that under your guidance the clean code style will continue and Mathias can take the leading role once the work for the remaining features is done.

In case of option 2: the only thing that I think is definitely missing for a lot of users is the auto-renewal feature.

ref @ffMathy @natemcmaster

@natemcmaster
Copy link
Owner Author

I'll give this another week, but if I don't get a response, I'm going to move forward with option 2 from this comment above #29 (comment).

Thanks for your feedback, @surfcode!

@erickguan
Copy link

One thing I prefer is to have deployment-related information in my JSON or environment variable. This is the reason I choose natemcmaster. fluffyspoon's auto-renewal is useful but a nested cron job will do for me now.

@ffMathy
Copy link

ffMathy commented Jan 11, 2020

@natemcmaster I'll come up with a response soon. It's complicated, and takes some time to formulate, so I haven't had the proper time to focus on it, but I'll hopefully have time tomorrow.

@PaulDMendoza
Copy link

Add an AWS Route53 DNS option. I have a server that isn't accessible to the internet that I need to generate the certificate using DNS. But it doesn't seem to work.

@natemcmaster
Copy link
Owner Author

Thanks everybody for the feedback on this issue. Based on your suggestions, I'm going to keep working on this project. I've written up #50 to propose where I think this project should go in the coming months. I'm open to more suggestions! Feel free to open an issue to propose your feature. Like many of you, open-source projects are a free-time activity and compete with raising a family and leisure activities. I appreciate your help and look forward to what we will create together.

@mika76
Copy link

mika76 commented Apr 16, 2020

A bit late to this convo but to add in my voice - wildcard subdomains and auto update 😊

@hubert-associates
Copy link

Nice! Is DNS-01 verification with AzureZones already possible for kestrel?

@hubert-associates
Copy link

Is cert renewal achieved by just repeating the procedure every time the .net-core server starts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests