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.
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.
* `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.
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
Client providers may verify the HTTPS certificate provided by the ACME server.
To do so, override the `createHttpConnector()` method of `AbstractAcmeProvider` and return a subclassed `HttpConnector` class that modifies the `HttpURLConnection` as necessary.
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.
## 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.
## 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.
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="Pebble" href="ca/pebble.html"/>
</item>
<item name="ACME Provider" href="provider.html"/>
<item name="Development" href="development/index.html">
<item name="ACME Provider" href="provider.html"/>
<item name="Testing" href="testing.html"/>
</item>
</menu>
<menu ref="modules"/>
<menu ref="reports"/>