comparison Sphinx/source/plugins/object-storage.rst @ 451:938206110483

added object storage
author Alain Mazy <alain@mazy.be>
date Fri, 03 Jul 2020 12:52:11 +0200
parents
children aef5c8b74381
comparison
equal deleted inserted replaced
450:235a5541e06e 451:938206110483
1 .. _object-storage:
2
3
4 Cloud Object Storage plugins
5 ============================
6
7 .. contents::
8
9
10 Introduction
11 ------------
12
13 Osimis freely provides the `source code
14 <https://hg.orthanc-server.com/orthanc-object-storage/file/default/>`__ of 3 plugins
15 to store the Orthanc files in `Object Storage <https://en.wikipedia.org/wiki/Object_storage>`__
16 at the 3 main providers: `AWS <https://aws.amazon.com/s3/>`__,
17 `Azure <https://azure.microsoft.com/en-us/services/storage/blobs/>`__ &
18 `Google Cloud <https://cloud.google.com/storage>`__
19
20 Storing Orthanc files in object storage and your index SQL in a
21 managed database allows you to have a stateless Orthanc that does
22 not store any data in its local file system which is highly recommended
23 when deploying an application in the cloud.
24
25
26 Compilation
27 -----------
28
29 .. highlight:: text
30
31 The procedure to compile the plugins is quite similar of that for the
32 :ref:`core of Orthanc <compiling>` although they usually require
33 some prerequisites. The documented procedure has been tested only
34 on a Debian Buster machine.
35
36 The compilation of each plugin produces a shared library that contains
37 the plugin.
38
39 Given thes plugins are used to interface with a commercial & proprietary
40 service, pre-compiled Windows/Docker binaries are available only for
41 companies who have subscribed for a `support contract <https://www.osimis.io/en/services.html#cloud-plugins>`__ at Osimis.
42
43
44 AWS S3 plugin
45 ^^^^^^^^^^^^^
46
47 Prerequisites: Compile the AWS C++ SDK::
48
49 $ mkdir ~/aws
50 $ cd ~/aws
51 $ git clone https://github.com/aws/aws-sdk-cpp.git
52 $
53 $ mkdir -p ~/aws/builds/aws-sdk-cpp
54 $ cd ~/aws/builds/aws-sdk-cpp
55 $ cmake -DBUILD_ONLY="s3;transfer" ~/aws/aws-sdk-cpp
56 $ make -j 4
57 $ make install
58
59 Prerequisites: Install `vcpkg <https://github.com/Microsoft/vcpkg>`__ dependencies::
60
61 $ ./vcpkg install cryptopp
62
63 Compile::
64
65 $ mkdir -p build/aws
66 $ cd build/aws
67 $ cmake -DCMAKE_TOOLCHAIN_FILE=[vcpkg root]\scripts\buildsystems\vcpkg.cmake ../../orthanc-object-storage/Aws
68
69 Azure Blob Storage plugin
70 ^^^^^^^^^^^^^^^^^^^^^^^^^
71
72 Prerequisites: Install `vcpkg <https://github.com/Microsoft/vcpkg>`__ dependencies::
73
74 $ ./vcpkg install cpprestsdk
75
76
77 Compile::
78
79 $ mkdir -p build/azure
80 $ cd build/azure
81 $ cmake -DCMAKE_TOOLCHAIN_FILE=[vcpkg root]\scripts\buildsystems\vcpkg.cmake ../../orthanc-object-storage/Azure
82
83 Google Storage plugin
84 ^^^^^^^^^^^^^^^^^^^^^
85
86 Prerequisites: Install `vcpkg <https://github.com/Microsoft/vcpkg>`__ dependencies::
87
88 $ ./vcpkg install google-cloud-cpp
89 $ ./vcpkg install cryptopp
90
91 Compile::
92
93 $ mkdir -p build/google
94 $ cd build/google
95 $ cmake -DCMAKE_TOOLCHAIN_FILE=[vcpkg root]\scripts\buildsystems\vcpkg.cmake ../../orthanc-object-storage/google
96
97
98 Configuration
99 -------------
100
101 .. highlight:: json
102
103 AWS S3 plugin
104 ^^^^^^^^^^^^^
105
106 Sample configuration::
107
108 "AwsS3Storage" : {
109 "BucketName": "test-orthanc-s3-plugin",
110 "Region" : "eu-central-1",
111 "AccessKey" : "AKXXX",
112 "SecretKey" : "RhYYYY"
113 }
114
115 Azure Blob Storage plugin
116 ^^^^^^^^^^^^^^^^^^^^^^^^^
117
118 Sample configuration::
119
120 "AzureBlobStorage" : {
121 "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=xxxxxxxxx;AccountKey=yyyyyyyy===;EndpointSuffix=core.windows.net",
122 "ContainerName" : "test-orthanc-storage-plugin"
123 }
124
125
126 Google Storage plugin
127 ^^^^^^^^^^^^^^^^^^^^^
128
129 Sample configuration::
130
131 "GoogleCloudStorage" : {
132 "ServiceAccountFile": "/path/to/googleServiceAccountFile.json",
133 "BucketName": "test-orthanc-storage-plugin"
134 }
135
136
137 Client-side encryption
138 ----------------------
139
140 Although all cloud providers already provide encryption at rest, the plugins provide
141 an optional layer of client-side encryption . It is very important that you understand
142 the scope and benefits of this additional layer of encryption.
143
144 Rationale
145 ^^^^^^^^^
146
147 Encryption at rest provided by cloud providers basically compares with a file-system disk encryption.
148 If someone has access to the disk, he won't have access to your data without the encryption key.
149
150 With cloud encryption at rest only, if someone has access to the "api-key" of your storage or if one
151 of your admin inadvertently make your storage public, `PHI <https://en.wikipedia.org/wiki/Protected_health_information>`__ will leak.
152
153 Once you use client-side encryption, you'll basically store packets of meaningless bytes on the cloud infrastructure.
154 So, if an "api-key" leaks or if the storage is misconfigured, packets of bytes will leak but not PHI since
155 no one will be able to decrypt them.
156
157 Another advantage is that these packets of bytes might eventually not be considered as PHI anymore and eventually
158 help you meet your local regulations (Please check your local regulations).
159
160 However, note that, if you're running entirely in a cloud environment, your decryption keys will still
161 be stored on the cloud infrastructure (VM disks - process RAM) and an attacker could still eventually gain access to this keys.
162 Furthermore, in the scope of the `Cloud Act <https://en.wikipedia.org/wiki/CLOUD_Act>`__ , the cloud provider might still have
163 the possibility to retrieve your data and encryption key (while it will still be more complex than with standard encryption at rest).
164
165 If Orthanc is running in your infrastructure with the Index DB on your infrastructure, and files are store in the cloud,
166 the master keys will remain on your infrastructure only and there's no way the data stored in the cloud could be decrypted outside your infrastructure.
167
168 Also note that, although the cloud providers also provide client-side encryption, we, as an open-source project,
169 wanted to provide our own implementation on which you'll have full control and extension capabilities.
170 This also allows us to implement the same logic on all cloud providers.
171
172 Our encryption is based on well-known standards (see below). Since it is documented and the source code is open-source,
173 feel-free to have your security expert review it before using it in a production environment.
174
175 Technical details
176 ^^^^^^^^^^^^^^^^^
177
178 Orthanc saves 2 kind of files: DICOM files and JSON summaries of DICOM files. Both files contain PHI.
179
180 When configuring the plugin, you'll have to provide a `Master Key` that we can also call the `Key Encryption Key` (KEK).
181
182 For each file being saved, the plugin will generate a new `Data Encryption Key` (DEK). This DEK, encrypted with the KEK will be pre-pended to the file.
183
184 If, at any point, your KEK leaks or you want to rotate your KEKs, you'll be able to use a new one to encrypt new files that are being added
185 and still use the old ones to decrypt data. You could then eventually start a side script to remove usages of the leaked/obsolete KEKs.
186
187 To summarize:
188
189 - We use `Crypto++<https://www.cryptopp.com/>`__ to perform all encryptions.
190 - All keys (KEK and DEK) are AES-256 keys.
191 - DEKs and IVs are encrypted by KEK using CTR block cipher using a null IV.
192 - data is encrypted by DEK using GCM block cipher that will also perform integrity check on the whole file.
193
194 The format of data stored on disk is therefore the following:
195
196 - **VERSION HEADER**: 2 bytes: identify the structure of the following data currently `A1`
197 - **MASTER KEY ID**: 4 bytes: a numerical ID of the KEK that was used to encrypt the DEK
198 - **EIV**: 32 bytes: IV used by DEK for data encryption; encrypted by KEK
199 - **EDEK**: 32 bytes: the DEK encrypted by the KEK.
200 - **CIPHER TEXT**: variable length: the DICOM/JSON file encrypted by the DEK
201 - **TAG**: 16 bytes: integrity check performed on the whole encrypted file (including header, master key id, EIV and EDEK)
202
203 Configuration
204 ^^^^^^^^^^^^^
205
206 .. highlight:: text
207
208 AES Keys shall be 32 bytes long (256 bits) and encoded in base64. Here's a sample OpenSSL command to generate such a key::
209
210 openssl rand -base64 -out /tmp/test.key 32
211
212 Each key must have a unique id that is a uint32 number.
213
214 .. highlight:: json
215
216 Here's a sample configuration file of the `StorageEncryption` section of the plugins::
217
218 {
219 "StorageEncryption" : {
220 "Enable": true,
221 "MasterKey": [3, "/path/to/master.key"], // key id - path to the base64 encoded key
222 "PreviousMasterKeys" : [
223 [1, "/path/to/previous1.key"],
224 [2, "/path/to/previous2.key"]
225 ],
226 "MaxConcurrentInputSize" : 1024 // size in MB
227 }
228 }
229
230 **MaxConcurrentInputSize**: Since the memory used during encryption/decryption can grow up to a bit more
231 than 2 times the input, we want to limit the number of threads doing concurrent processing according
232 to the available memory instead of the number of concurrent threads. Therefore, if you're currently
233 ingesting small files, you can have a lot of thread working together while, if you're ingesting large
234 files, threads might have to wait before receiving a "slot" to access the encryption module.