crypt_reboot 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +29 -3
- data/lib/basic_loader.rb +1 -1
- data/lib/crypt_reboot/cli/params/definition.rb +6 -0
- data/lib/crypt_reboot/cli/params_parsing_executor.rb +2 -2
- data/lib/crypt_reboot/elastic_memory_locker.rb +42 -0
- data/lib/crypt_reboot/instantiable_config.rb +4 -1
- data/lib/crypt_reboot/version.rb +1 -1
- data/lib/crypt_reboot.rb +1 -0
- metadata +3 -17
- data/lib/crypt_reboot/memory_locker.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee0a1d8c466f902cc47c84b3310c899046ae2d2cacc952f184baa76463add807
|
4
|
+
data.tar.gz: 6fc17834b241d0822848b84e36fa2277b47a998c77659740a82d0e49d83a16e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 030a74f06349d21c91b05a7ac297ffb927309faad863689a8cd632521587e47059c38995b377e199e5337819f447999796f65aa6dfa17345f7aaca0821458a23
|
7
|
+
data.tar.gz: 2f16596ee0b871ecec49b9687da65d3086c66daa41b48e3090d43317452755752443996f5ef5887ac4a73f50f31bd4307ab08254b2869e3219970117ddfcbeee
|
data/README.md
CHANGED
@@ -65,12 +65,24 @@ If you use Debian-based distribution, use this command to install required packa
|
|
65
65
|
When asked if kexec should handle reboots, answer `yes` (however the answer probably
|
66
66
|
doesn't matter for cryptreboot to work).
|
67
67
|
|
68
|
+
## Recommendations
|
69
|
+
|
70
|
+
To protects against saving sensitive data (passphrase, encryption keys) to swap space on a disk, it is recommended to use `memory_locker` ([Rubygems](https://rubygems.org/gems/memory_locker), [Github](https://github.com/phantom-node/memory_locker)).
|
71
|
+
|
72
|
+
$ sudo gem install memory_locker
|
73
|
+
|
74
|
+
If you don't want to install it, you will have to specify `--insecure-memory` flag when running cryptreboot.
|
75
|
+
|
68
76
|
## Installation
|
69
77
|
|
70
78
|
Make sure the required software is installed, then install the gem system-wide by executing:
|
71
79
|
|
72
80
|
$ sudo gem install crypt_reboot
|
73
81
|
|
82
|
+
To upgrade run:
|
83
|
+
|
84
|
+
$ sudo gem update crypt_reboot
|
85
|
+
|
74
86
|
## Usage
|
75
87
|
|
76
88
|
Cryptreboot performs operations normally only available to the root user,
|
@@ -84,7 +96,7 @@ To see the usage, run:
|
|
84
96
|
|
85
97
|
$ cryptreboot --help
|
86
98
|
|
87
|
-
##
|
99
|
+
## Troubleshooting
|
88
100
|
|
89
101
|
### LZ4 initramfs compression
|
90
102
|
|
@@ -140,9 +152,9 @@ To cancel the change, remove the file:
|
|
140
152
|
|
141
153
|
$ sudo rm /etc/systemd/system/systemd-kexec.service.d/override.conf
|
142
154
|
|
143
|
-
### No symlinks to most recent kernel and initramfs
|
155
|
+
### No symlinks to the most recent kernel and initramfs
|
144
156
|
|
145
|
-
By default cryptreboot looks for kernel in `/boot/vmlinuz` and for initramfs
|
157
|
+
By default, cryptreboot looks for kernel in `/boot/vmlinuz` and for initramfs
|
146
158
|
in `/boot/initrd.img`. If those files are missing in your Linux distribution,
|
147
159
|
cryptreboot will fail, unless you use `--kernel` and `--initramfs` command line
|
148
160
|
options.
|
@@ -160,6 +172,20 @@ Unfortunately, you need to rerun it after each kernel upgrade, otherwise,
|
|
160
172
|
cryptreboot is going to boot the old kernel.
|
161
173
|
Upcoming versions of cryptreboot will offer better solutions.
|
162
174
|
|
175
|
+
### Problems with memory locking
|
176
|
+
|
177
|
+
If you get:
|
178
|
+
|
179
|
+
> Locking error: Failed to lock memory
|
180
|
+
|
181
|
+
it means there was an error while locking memory to prevent a risk of sensitive data ending in a swap space.
|
182
|
+
|
183
|
+
The best solution is to install `memory_locker` (see [requirements](#requirements) section).
|
184
|
+
If it still doesn't help, make sure you have permission to lock memory. Root users do.
|
185
|
+
If the problem persists, then please report a bug describing your setup.
|
186
|
+
|
187
|
+
The solution of last resort is to use `--insecure-memory` flag, which disables memory locking completely.
|
188
|
+
|
163
189
|
## Development
|
164
190
|
|
165
191
|
After checking out the repo, run `bundle install` to install
|
data/lib/basic_loader.rb
CHANGED
@@ -8,13 +8,13 @@ require 'crypt_reboot/cli'
|
|
8
8
|
require 'crypt_reboot/concatenator'
|
9
9
|
require 'crypt_reboot/instantiable_config'
|
10
10
|
require 'crypt_reboot/config'
|
11
|
+
require 'crypt_reboot/elastic_memory_locker'
|
11
12
|
require 'crypt_reboot/files_generator'
|
12
13
|
require 'crypt_reboot/files_writer'
|
13
14
|
require 'crypt_reboot/gziper'
|
14
15
|
require 'crypt_reboot/initramfs_patch_squeezer'
|
15
16
|
require 'crypt_reboot/kexec_patching_loader'
|
16
17
|
require 'crypt_reboot/lazy_config'
|
17
|
-
require 'crypt_reboot/memory_locker'
|
18
18
|
require 'crypt_reboot/passphrase_asker'
|
19
19
|
require 'crypt_reboot/patched_initramfs_generator'
|
20
20
|
require 'crypt_reboot/rebooter'
|
@@ -90,6 +90,12 @@ module CryptReboot
|
|
90
90
|
'algorithm to a more robust one.'
|
91
91
|
end
|
92
92
|
|
93
|
+
flag :insecure_memory do
|
94
|
+
short '-s'
|
95
|
+
long '--insecure-memory'
|
96
|
+
desc 'Do not lock memory. WARNING: there is a risk your secrets will leak to swap.'
|
97
|
+
end
|
98
|
+
|
93
99
|
flag :debug do
|
94
100
|
short '-d'
|
95
101
|
long '--debug'
|
@@ -5,7 +5,6 @@ module CryptReboot
|
|
5
5
|
# Interprets parameters, executes everything and returns callable object
|
6
6
|
class ParamsParsingExecutor
|
7
7
|
def call(raw_params)
|
8
|
-
locker.call
|
9
8
|
params = parser.call(raw_params)
|
10
9
|
handle_action_params!(params) or configure_and_exec(params)
|
11
10
|
rescue StandardError, Interrupt => e
|
@@ -22,6 +21,7 @@ module CryptReboot
|
|
22
21
|
|
23
22
|
def configure_and_exec(params)
|
24
23
|
config_updater.call(**params)
|
24
|
+
locker.call
|
25
25
|
loader.call
|
26
26
|
rebooter
|
27
27
|
end
|
@@ -58,7 +58,7 @@ module CryptReboot
|
|
58
58
|
rebooter: Rebooter.new,
|
59
59
|
happy_exiter_class: HappyExiter,
|
60
60
|
sad_exiter_class: SadExiter,
|
61
|
-
locker:
|
61
|
+
locker: ElasticMemoryLocker.new)
|
62
62
|
@parser = parser
|
63
63
|
@config_updater = config_updater
|
64
64
|
@loader = loader
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CryptReboot
|
4
|
+
# Try to lock memory if configuration allows it
|
5
|
+
class ElasticMemoryLocker
|
6
|
+
LockingError = Class.new StandardError
|
7
|
+
|
8
|
+
def call
|
9
|
+
return if skip_locking?
|
10
|
+
|
11
|
+
loader.call
|
12
|
+
locker.call
|
13
|
+
nil
|
14
|
+
rescue load_error, locking_error => e
|
15
|
+
raise LockingError, 'Failed to lock memory', cause: e
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def skip_locking?
|
21
|
+
insecure_memory_checker.call
|
22
|
+
end
|
23
|
+
|
24
|
+
def locking_error
|
25
|
+
lazy_locking_error.call
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :insecure_memory_checker, :loader, :load_error, :locker, :lazy_locking_error
|
29
|
+
|
30
|
+
def initialize(insecure_memory_checker: LazyConfig.insecure_memory,
|
31
|
+
loader: -> { require 'memory_locker' },
|
32
|
+
load_error: LoadError,
|
33
|
+
locker: -> { MemoryLocker.call },
|
34
|
+
lazy_locking_error: -> { MemoryLocker::Error })
|
35
|
+
@insecure_memory_checker = insecure_memory_checker
|
36
|
+
@loader = loader
|
37
|
+
@load_error = load_error
|
38
|
+
@locker = locker
|
39
|
+
@lazy_locking_error = lazy_locking_error
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -8,7 +8,7 @@ module CryptReboot
|
|
8
8
|
attr_reader :initramfs, :cmdline, :kernel, :patch_save_path, :cat_path, :cpio_path,
|
9
9
|
:unmkinitramfs_path, :kexec_path, :cryptsetup_path, :reboot_path,
|
10
10
|
:mount_path, :umount_path, :strace_path, :grep_path,
|
11
|
-
:debug, :prepare_only, :skip_lz4_check
|
11
|
+
:debug, :prepare_only, :skip_lz4_check, :insecure_memory
|
12
12
|
|
13
13
|
def update!(**settings)
|
14
14
|
settings.each do |name, value|
|
@@ -25,6 +25,7 @@ module CryptReboot
|
|
25
25
|
end
|
26
26
|
|
27
27
|
# rubocop:disable Metrics/MethodLength
|
28
|
+
# rubocop:disable Metrics/AbcSize
|
28
29
|
def initialize
|
29
30
|
# Options
|
30
31
|
@initramfs = '/boot/initrd.img'
|
@@ -46,7 +47,9 @@ module CryptReboot
|
|
46
47
|
@debug = false
|
47
48
|
@prepare_only = false
|
48
49
|
@skip_lz4_check = false
|
50
|
+
@insecure_memory = false
|
49
51
|
end
|
52
|
+
# rubocop:enable Metrics/AbcSize
|
50
53
|
# rubocop:enable Metrics/MethodLength
|
51
54
|
end
|
52
55
|
end
|
data/lib/crypt_reboot/version.rb
CHANGED
data/lib/crypt_reboot.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crypt_reboot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paweł Pokrywka
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-07-
|
11
|
+
date: 2023-07-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tty-command
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.3'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: ffi
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 1.0.0
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 1.0.0
|
55
41
|
description:
|
56
42
|
email:
|
57
43
|
- pepawel@users.noreply.github.com
|
@@ -85,6 +71,7 @@ files:
|
|
85
71
|
- lib/crypt_reboot/crypt_tab/keyfile_locator.rb
|
86
72
|
- lib/crypt_reboot/crypt_tab/luks_to_plain_converter.rb
|
87
73
|
- lib/crypt_reboot/crypt_tab/serializer.rb
|
74
|
+
- lib/crypt_reboot/elastic_memory_locker.rb
|
88
75
|
- lib/crypt_reboot/files_generator.rb
|
89
76
|
- lib/crypt_reboot/files_writer.rb
|
90
77
|
- lib/crypt_reboot/gziper.rb
|
@@ -107,7 +94,6 @@ files:
|
|
107
94
|
- lib/crypt_reboot/luks/dumper/luks_v2_parser.rb
|
108
95
|
- lib/crypt_reboot/luks/key_fetcher.rb
|
109
96
|
- lib/crypt_reboot/luks/version_detector.rb
|
110
|
-
- lib/crypt_reboot/memory_locker.rb
|
111
97
|
- lib/crypt_reboot/passphrase_asker.rb
|
112
98
|
- lib/crypt_reboot/patched_initramfs_generator.rb
|
113
99
|
- lib/crypt_reboot/rebooter.rb
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'ffi'
|
4
|
-
|
5
|
-
module CryptReboot
|
6
|
-
# Lock process memory, so it won't be swapped by the kernel.
|
7
|
-
# It is implemented as a one-way operation: there is no unlock.
|
8
|
-
# That's because it's hard to properly clean memory in Ruby.
|
9
|
-
class MemoryLocker
|
10
|
-
Error = Class.new StandardError
|
11
|
-
|
12
|
-
def call
|
13
|
-
return if Libc.mlockall(Libc::MCL_CURRENT | Libc::MCL_FUTURE).zero?
|
14
|
-
|
15
|
-
raise Error, "Failed to lock memory: #{FFI.errno}"
|
16
|
-
end
|
17
|
-
|
18
|
-
# Low level interface to libc
|
19
|
-
module Libc
|
20
|
-
extend FFI::Library
|
21
|
-
ffi_lib 'libc.so.6'
|
22
|
-
|
23
|
-
# define mlockall constants
|
24
|
-
MCL_CURRENT = 1
|
25
|
-
MCL_FUTURE = 2
|
26
|
-
MCL_ONFAULT = 4
|
27
|
-
|
28
|
-
# declare mlockall function
|
29
|
-
attach_function :mlockall, [:int], :int
|
30
|
-
end
|
31
|
-
private_constant :Libc
|
32
|
-
end
|
33
|
-
end
|