diff --git a/src/site/markdown/development/index.md b/src/site/markdown/development/index.md new file mode 100644 index 00000000..6c65ec8b --- /dev/null +++ b/src/site/markdown/development/index.md @@ -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) diff --git a/src/site/markdown/provider.md b/src/site/markdown/development/provider.md similarity index 53% rename from src/site/markdown/provider.md rename to src/site/markdown/development/provider.md index 55b48f8f..caa1296f 100644 --- a/src/site/markdown/provider.md +++ b/src/site/markdown/development/provider.md @@ -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. diff --git a/src/site/markdown/development/testing.md b/src/site/markdown/development/testing.md new file mode 100644 index 00000000..5f8cc362 --- /dev/null +++ b/src/site/markdown/development/testing.md @@ -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. diff --git a/src/site/markdown/index.md.vm b/src/site/markdown/index.md.vm index 1031bd37..bc2cfbd8 100644 --- a/src/site/markdown/index.md.vm +++ b/src/site/markdown/index.md.vm @@ -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. diff --git a/src/site/site.xml b/src/site/site.xml index bc12b38d..cbda489f 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -45,7 +45,10 @@ - + + + +