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

Certificate rotation #778

Open
juananinca opened this issue May 9, 2022 · 3 comments
Open

Certificate rotation #778

juananinca opened this issue May 9, 2022 · 3 comments

Comments

@juananinca
Copy link

Is your feature request related to a problem? Please describe.
If consul certificates are rotated, the running services won't be able to interact with consul anymore.

Describe the solution you'd like
It would work to have a watch over the certificates. Whenever a change is made on the consul tls config files, the consul client bean will reload the new certificates and be able to comunicate with consul with the news certs.

Describe alternatives you've considered
I have looked for any other issue created, but I didn't find anything related. Any other aproach to deal with the certificate rotation would be welcomed.

@spencergibb
Copy link
Member

How would the client watch certificates? Where are they located?

@spring-cloud-issues
Copy link

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

@juananinca
Copy link
Author

I did a workaround in order to make consul-api library to be able to refresh the certs when needed.
This use case happens in a spring boot application along with 'org.springframework.cloud:spring-cloud-starter-consul'. This workaround is far from being a PR but I think it shows my point.

I implemented a cron bean in my application with the https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/filewatch/FileSystemWatcher.java class and every time the cert is modified, the consulClient bean is asked to refresh its certs from the ConsulRawClient's httpTransport property.

I added a new attribute called lastTlsConfigLoaded which is a com.ecwid.consul.transport.TLSConfig in the ConsulRawClient class. Thus when the new method refreshTlsConnection is called can use the last tls config used to create a new HttpTransport object. Besides the httpTransport now is not final.

public class ConsulRawClient {

    [....]

	private HttpTransport httpTransport;
	private final String agentAddress;
	private TLSConfig lastTlsConfigLoaded;

	public static final class Builder {
		
        [....]

		private TLSConfig lastTlsConfigLoaded;

		public static ConsulRawClient.Builder builder() {
			return new ConsulRawClient.Builder();
		}

        [.....]

		public Builder setTlsConfig(TLSConfig tlsConfig) {
			this.httpTransport = new DefaultHttpsTransport(tlsConfig);
			this.lastTlsConfigLoaded = tlsConfig;
			return this;
		}

        [....]

		public ConsulRawClient build() {
			ConsulRawClient consulRawClient = new ConsulRawClient(httpTransport, agentHost, agentPort, agentPath);
			consulRawClient.lastTlsConfigLoaded = this.lastTlsConfigLoaded;
			return consulRawClient;
		}
	}

	[....]

	public void refreshTlsConnection() {
		this.httpTransport = new DefaultHttpsTransport(this.lastTlsConfigLoaded);
	}

}

And some additional changes have to been made in the ConsulClient class, adding a new ConsulRawClient attribute:

public class ConsulClient implements
		AclClient,
		AgentClient,
		CatalogClient,
		CoordinateClient,
		EventClient,
		HealthClient,
		KeyValueClient,
		QueryClient,
		SessionClient,
		StatusClient {

	[.....]
	private final ConsulRawClient consulRawClient;

	public ConsulClient(ConsulRawClient rawClient) {
		this.consulRawClient = rawClient;
		aclClient = new AclConsulClient(this.consulRawClient);
		agentClient = new AgentConsulClient(this.consulRawClient);
        [....]
	}

    [.....]

	public void refreshTlsConnection() {
		this.consulRawClient.refreshTlsConnection();
	}
}

Note: it is important to point that this workaround won't work if the new certs are located in another path than the original one.

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

No branches or pull requests

3 participants