Files
ubicloud/migrate/20230811_add_nic_rekey_payload.rb
Furkan Sahin 85420ccc5a Private Subnet IpsecTunnel rekeying
With this commit, we introduce the mechanism to replace the encryption
keys for existing ipsec tunnels. Here is the detailed explanation of the
work;
1. Private Subnet nexus hops to the refresh_keys state when needed. Here
we are going through a preparation phase. We start producing new
encryption keys, SPIs and reqids for the new state and policy objects.
At the end of the day, we write the new encryption keys, SPIs and the
reqids to the nic entities.  So, for every nic in the system, we prepare
the new parameters at the private subnet level.
2. Trigger NicNexus to start rekeying.
3. NicNexus buds RekeyNicTunnel to create the SA objects for inbound
packets.  This part is important. Let me explain the current state of
the tunnelling in detail here. Please refer to the end of the commit
message.
3. The RekeyNic prog in  setup_inbound state, first finds all the state
objects required to be created at the destination end. This way, no
matter when the source policy/state is updated, the receiving end will
be ready with the encryption key.
4. Once everyone creates their receiving end state objects, we switch to
update the sender (aka outbound). This ping-pong is managed via
SubnetNexus by checking the state of NicNexus strands and using
semaphores to progress the state machine. This part of the code means
any packet that is being created at this moment, will be encrypted with
the new keys.
5. Once everyone in the mesh has created/updated their sender policies
and state objects. We go ahead and drop the state objects that are not
referenced by any policy.

Ipsec Tunneling
Each tunnel has two ends <source_nic> and <destination_nic>. For a
tunnel to work, both ends need to know about the encryption key so that
they can either encrypt or decrypt the packet. However, the encryption
key is not sent over with the packet. Therefore, the key must exist
locally in both systems. How does it work? Firstly, I should tell you
about the 2 objects we use to implement ipsec tunnels.
1. Policy:
Policies are used to capture packages and apply encryption. The way it
works is easy. All the packets are observed and if there is a packet
that matches one of the policies we created, we capture the reqid from
the policy. The reqid is the unique identifier of a state object that
has the encryption key information. Therefore, if a policy is matched,
we get the reqid from the policy, find the matching state object and
encrypt the packet using the encryption key, send it to the networking
stack again.
2. State:
States are there to store the encryption key information. They also have
fields like spi and reqid. reqid is mentioned in the policy part, so,
for outgoing connections, reqid is used to identify the encryption key.
For incoming connections, that is spi because spi is sent with the
packet in the header so that when receiving end gets the packet, finds a
matching policy, the spi is read from the header and the encryption key
is identified. This gives us the flexibility of using multiple state
objects for 1 tunnel. Also, handy for the rekeying process.
2023-08-17 09:38:44 +02:00

10 lines
146 B
Ruby

# frozen_string_literal: true
Sequel.migration do
change do
alter_table(:nic) do
add_column :rekey_payload, :jsonb
end
end
end