Add documentation for acme4j developers

pull/55/head
Richard Körber 2018-01-08 00:51:58 +01:00
parent d53e878835
commit 334ac0354f
No known key found for this signature in database
GPG Key ID: AAB9FD19C78AA3E0
5 changed files with 65 additions and 18 deletions

View File

@ -0,0 +1,6 @@
# _acme4j_ Development
This part of the documentation is addressed to developers who want to extend _acme4j_, or who want to use _acme4j_ for integration tests.
* [Write an own Provider extension](./provider.html)
* [Integration Tests](./testing.html)

View File

@ -18,7 +18,7 @@ Every CA that provides an ACME server should also have an own `AcmeProvider`, an
However, it is also possible to adapt the behavior of wide parts of _acme4j_ to special characteristics of the CA, just by overriding methods and extending classes. However, it is also possible to adapt the behavior of wide parts of _acme4j_ to special characteristics of the CA, just by overriding methods and extending classes.
A client provider implements the [`AcmeProvider`](./apidocs/org/shredzone/acme4j/provider/AcmeProvider.html) interface, but usually it is easier to extend [`AbstractAcmeProvider`](./apidocs/org/shredzone/acme4j/provider/AbstractAcmeProvider.html) and implement only these two methods: A client provider implements the [`AcmeProvider`](../apidocs/org/shredzone/acme4j/provider/AcmeProvider.html) interface, but usually it is easier to extend [`AbstractAcmeProvider`](../apidocs/org/shredzone/acme4j/provider/AbstractAcmeProvider.html) and implement only these two methods:
* `accepts(URI)` checks if the client provider is accepting the provided URI. Usually it would be an URI like `acme://example.com`. Note that the `http` and `https` schemes are reserved for the generic provider and cannot be used by other providers. * `accepts(URI)` checks if the client provider is accepting the provided URI. Usually it would be an URI like `acme://example.com`. Note that the `http` and `https` schemes are reserved for the generic provider and cannot be used by other providers.
* `resolve(URI)` parses that URI and returns the corresponding URL of the directory service. * `resolve(URI)` parses that URI and returns the corresponding URL of the directory service.
@ -27,20 +27,31 @@ The `AcmeProvider` implementation needs to be registered with Java's `ServiceLoa
When _acme4j_ tries to connect to an acme URI, it first invokes the `accepts(URI)` method of all registered `AcmeProvider`s. Only one of the providers must return `true` for a successful connection. _acme4j_ then invokes the `resolve(URI)` method of that provider, and connects to the directory URL that is returned. When _acme4j_ tries to connect to an acme URI, it first invokes the `accepts(URI)` method of all registered `AcmeProvider`s. Only one of the providers must return `true` for a successful connection. _acme4j_ then invokes the `resolve(URI)` method of that provider, and connects to the directory URL that is returned.
The connection fails if no or more than one `AcmeProvider` implementations accept the acme URI. The connection fails if no or more than one `AcmeProvider` implementation accepts the acme URI.
## Certificate Pinning ## Certificate Pinning
Client providers may verify the HTTPS certificate provided by the ACME server. The standard Java mechanisms are used to verify the HTTPS certificate provided by the ACME server. To pin the certificate, or use a self-signed certificate, override the `createHttpConnector()` method of `AbstractAcmeProvider` and return a subclassed `HttpConnector` class that modifies the `HttpURLConnection` as necessary.
To do so, override the `createHttpConnector()` method of `AbstractAcmeProvider` and return a subclassed `HttpConnector` class that modifies the `HttpURLConnection` as necessary.
## Individual Challenges ## Individual Challenges
If your ACME server provides challenges that are not specified in the ACME protocol, there should be an own `Challenge` implementation for each of your challenge, by extending the [`Challenge`](./apidocs/org/shredzone/acme4j/challenge/Challenge.html) class. If your ACME server provides challenges that are not specified in the ACME protocol, there should be an own `Challenge` implementation for each of your challenge, by extending the [`Challenge`](../apidocs/org/shredzone/acme4j/challenge/Challenge.html) class.
In your `AcmeProvider` implementation, override the `createChallenge(Session, String)` method so it returns a new instance of your `Challenge` implementation when your individual challenge type is requested. All other types should be delegated to the super method. In your `AcmeProvider` implementation, override the `createChallenge(Session, String)` method so it returns a new instance of your `Challenge` implementation when your individual challenge type is requested. All other types should be delegated to the super method.
## No directory service ## Amended Directory Service
To modify the directory of an ACME server, or use a static directory, override the `directory(Session, URI)` method, and return a `JSON` of all available resources and their respective URL. To override single entries of an ACME server's directory, or to use a static directory, override the `directory(Session, URI)` method, and return a `JSON` of all available resources and their respective URL.
## Adding your Provider to _acme4j_
After you completed your provider code, you can send in a pull request and have it added to the _acme4j_ code base, if these preconditions are met:
* Your provider's source code must be published under the terms of [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0).
* The source code of your ACME server must be publicly available under an [OSI compliant license](https://opensource.org/licenses/alphabetical).
* To avoid name conflicts, the `acme:` URI used must have the official domain name of your service as domain part.
* You have the permission of all trademark holders involved, to use their trademarks in the source codes, package names, and the acme URI.
The _acme4j_ development team reserves the right to reject your pull request, without giving any reason.
If you cannot meet these preconditions, you can always publish a JAR package of your _acme4j_ provider yourself. Due to the plug-in nature of _acme4j_ providers, it is sufficient to have that package in the Java classpath at runtime. There is no need to publish the source code.

View File

@ -0,0 +1,36 @@
# Testing _acme4j_
## Integration Tests
_acme4j_ provides a number of integration tests. These tests are _not_ executed by maven by default, as they require Docker on the build machine.
To run them, install Docker and make it available to your user. Then invoke `mvn -Pci verify` to run the integration tests. The test will build images of the current [Pebble ACME test server](https://github.com/letsencrypt/pebble), and an internal test server that provides a configurable HTTP and DNS server for Pebble.
If you change into the `acme-it` project directory, you can also build, start and stop the test servers with `mvn docker:build`, `mvn docker:start` and `mvn docker:stop`, respectively. While the test servers are running, you can also run the integration tests in your IDE. `mvn docker:remove` finally removes the test server images.
## BammBamm
The `acme4j-it` module contains a small and very simple test server called _BammBamm_, which can be used to verify challenges. In the default configuration, it uses these ports:
* 14001: Provides a simple REST-like interface for adding and removing challenge tokens and DNS records. This port is exposed.
* 53 (UDP): A simple DNS server for resolving test domain names, and providing `TXT` records for `dns-01` challenges.
* 5001: A simple HTTP server that responses with certificates for `tls-sni-02` challenges.
* 5002: A simple HTTP server that responses with tokens for `http-01` challenges.
To run this server, you can use the Docker image mentioned above. You could also run the server directly, but since the DNS server is listening on a privileged port, it would need to be reconfigured first.
The `BammBammClient` class can be used to set the challenge responses and DNS records via the REST interface on port 14001.
Note that _BammBamm_ has its main focus on simplicity, and is only meant as a server for integration test purposes. Do not use _Bammbamm_ in production environments! It is neither hardened, nor feature complete.
## Boulder
It is also possible to run some tests against the [Boulder](https://github.com/letsencrypt/boulder) ACME server, but the setup is a little tricky.
First, build and start the integration test Docker servers as [explained above](#Integration_Tests). When the servers are started, find out the IP address of the _BammBamm_ server (`docker inspect bammbamm -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'`). You'll need it in the next step.
Now set up a Docker instance of Boulder. Follow the instructions in the [Boulder README](https://github.com/letsencrypt/boulder#quickstart). When you are ready to start it, set the `FAKE_DNS` env variable to the IP address of _BammBamm_ you have found before.
The Boulder integration tests can now be run with `mvn -P boulder verify`.
For a local Boulder installation, just make sure that `FAKE_DNS` is set to `127.0.0.1`. You'll also need to expose the ports 5001 and 5002 of _BammBamm_ by changing the `acme4j-it/pom.xml` accordingly.

View File

@ -35,12 +35,3 @@ There is also an optional utility module that will help you handling key pairs a
``` ```
Now just have a look at [this source code](https://github.com/shred/acme4j/blob/master/acme4j-example/src/main/java/org/shredzone/acme4j/ClientTest.java) to see an example usage. Now just have a look at [this source code](https://github.com/shred/acme4j/blob/master/acme4j-example/src/main/java/org/shredzone/acme4j/ClientTest.java) to see an example usage.
Running Integration Tests
-------------------------
_acme4j_ provides a number of integration tests. These tests are _not_ executed by maven by default, as they require Docker on the build machine.
To run them, install Docker and make it available to your user. Then invoke `mvn -Pci verify` to run the integration tests. The tests build images of the current [Pebble ACME test server](https://github.com/letsencrypt/pebble), and an internal test server that provides a configurable HTTP and DNS server for Pebble.
If you change into the `acme-it` project directory, you can also build, start and stop the test servers with `mvn docker:build`, `mvn docker:start` and `mvn docker:stop`, respectively. While the test servers are running, you can execute the integration tests in your IDE.

View File

@ -45,7 +45,10 @@
<item name="Let's Encrypt" href="ca/letsencrypt.html"/> <item name="Let's Encrypt" href="ca/letsencrypt.html"/>
<item name="Pebble" href="ca/pebble.html"/> <item name="Pebble" href="ca/pebble.html"/>
</item> </item>
<item name="Development" href="development/index.html">
<item name="ACME Provider" href="provider.html"/> <item name="ACME Provider" href="provider.html"/>
<item name="Testing" href="testing.html"/>
</item>
</menu> </menu>
<menu ref="modules"/> <menu ref="modules"/>
<menu ref="reports"/> <menu ref="reports"/>