Remove additional-serialization-bindings, #26684

This should be safe for a rolling update between Akka 2.5.x and 2.6.0
also if additional-bindings were disabled in 2.5.x because:
* if 2.6.0 sends one of those the serializer (akka-misc) exists in 2.5.x
  so deserialization will work via the serializerId
* if 2.5.x sends one of those with java serialization it can be
  deserialized in 2.6.0 since the java serializer exists
  (disabling java serialization by default is another ticket)

* historical problems with serialization of remote Deploy messages
  in Akka 2.4.x should be gone now
This commit is contained in:
Patrik Nordwall 2019-07-03 13:00:47 +02:00
parent 2db03309ce
commit 3f4179c316
12 changed files with 48 additions and 236 deletions

View file

@ -146,7 +146,3 @@ manual exception overrides may be put in place if the change happened to be in a
Scala does not maintain serialization compatibility across major versions. This means that if Java serialization is used
there is no guarantee objects can be cleanly deserialized if serialized with a different version of Scala.
The internal Akka Protobuf serializers that can be enabled explicitly with `enable-additional-serialization-bindings`
or implicitly with `akka.actor.allow-java-serialization = off` (which is preferable from a security standpoint)
does not suffer from this problem.

View file

@ -55,26 +55,6 @@ implements `java.io.Serializable`, protobuf messages will always be
serialized using the protobuf protocol unless specifically overridden. In order
to disable a default serializer, see @ref:[Disabling the Java Serializer](remoting-artery.md#disable-java-serializer)
### Enable additional bindings
A few types in Akka are, for backwards-compatibility reasons, still serialized by using Java serializer by default.
You can switch them to using protocol buffers instead by adding the following bindings or set `akka.actor.allow-java-serialization=off`, which will make them serialized using protocol buffers instead.
Refer to @ref[Rolling Upgrades](#rolling-upgrades) to understand how it is possible to turn and start using these new
serializers in your clustered applications.
You can enable them one by one adding by adding their bindings to the misc serializer, like this:
```
akka.actor.serialization-bindings {
"akka.Done" = akka-misc
"akka.NotUsed" = akka-misc
"akka.actor.Address" = akka-misc
"akka.remote.UniqueAddress" = akka-misc
}
```
Alternatively, you can disable all Java serialization which then automatically will add the `java-serialization-disabled-additional-serialization-bindings` bindings to the active bindings.
### Verification
Normally, messages sent between local actors (i.e. same JVM) do not undergo serialization. For testing, sometimes, it may be desirable to force serialization on all messages (both remote and local). If you want to do this in order to verify that your messages are serializable you can enable the following config option:
@ -258,57 +238,14 @@ The recommended approach to do deep serialization of internal actor state is to
<a id="disable-java-serializer"></a>
## Disabling the Java Serializer
Since the `2.4.11` release of Akka it is possible to entirely disable the default Java Serialization mechanism.
For compatibility reasons, the current (non-Artery) @ref:[Remoting](remoting.md) still uses Java
serialization for some classes, however you can disable it in this remoting implementation as well by following
the steps below.
The first step is to enable some additional serializers that replace previous Java serialization of some internal
messages. This is recommended also when you can't disable Java serialization completely. Those serializers are
enabled with this configuration:
```ruby
akka.actor {
# Set this to on to enable serialization-bindings defined in
# additional-serialization-bindings. Those are by default not included
# for backwards compatibility reasons. They are enabled by default if
# akka.remote.artery.enabled=on.
enable-additional-serialization-bindings = on
}
```
The reason these are not enabled by default is wire-level compatibility between any 2.4.x Actor Systems.
If you roll out a new cluster, all on the same Akka version that can enable these serializers it is recommended to
enable this setting. When using @ref:[Remoting (codename Artery)](remoting-artery.md) these serializers are enabled by default.
@@@ warning
Please note that when enabling the `additional-serialization-bindings` when using the old remoting,
you must do so on all nodes participating in a cluster, otherwise the mis-aligned serialization
configurations will cause deserialization errors on the receiving nodes.
@@@
Java serialization is known to be slow and [prone to attacks](https://community.hpe.com/t5/Security-Research/The-perils-of-Java-deserialization/ba-p/6838995)
of various kinds - it never was designed for high throughput messaging after all. However, it is very
convenient to use, thus it remained the default serialization mechanism that Akka used to
serialize user messages as well as some of its internal messages in previous versions.
Since the release of Artery, Akka internals do not rely on Java serialization anymore (one exception being `java.lang.Throwable`).
@@@ warning
Please note Akka 2.5 by default does not use any Java Serialization for its own internal messages, unlike 2.4 where
by default it still did for a few of the messages. If you want an 2.4.x system to communicate with a 2.5.x series, for
example during a rolling deployment you should first enable `additional-serialization-bindings` on the old systems.
You must do so on all nodes participating in a cluster, otherwise the mis-aligned serialization
configurations will cause deserialization errors on the receiving nodes. These additional serialization bindings are
enabled by default in Akka 2.5.x.
@@@
@@@ note
When using the new remoting implementation (codename Artery), Akka does not use Java Serialization for any of its internal messages.
Akka does not use Java Serialization for any of its internal messages.
It is highly encouraged to disable java serialization, so please plan to do so at the earliest possibility you have in your project.
One may think that network bandwidth and latency limit the performance of remote messaging, but serialization is a more typical bottleneck.
@ -332,8 +269,6 @@ This will completely disable the use of `akka.serialization.JavaSerialization` b
Akka Serialization extension, instead `DisabledJavaSerializer` will
be inserted which will fail explicitly if attempts to use java serialization are made.
It will also enable the above mentioned `enable-additional-serialization-bindings`.
The log messages emitted by such serializer SHOULD be treated as potential
attacks which the serializer prevented, as they MAY indicate an external operator
attempting to send malicious messages intending to use java serialization as attack vector.
@ -346,11 +281,6 @@ Please note that this option does not stop you from manually invoking java seria
It is not safe to mix major Scala versions when using the Java serialization as Scala does not guarantee compatibility
and this could lead to very surprising errors.
If using the Akka Protobuf serializers (implicitly with `akka.actor.allow-java-serialization = off` or explicitly with
`enable-additional-serialization-bindings = true`) for the internal Akka messages those will not require the same major
Scala version however you must also ensure the serializers used for your own types does not introduce the same
incompatibility as Java serialization does.
## Rolling upgrades
A serialized remote message (or persistent event) consists of serializer-id, the manifest, and the binary payload.