crypt_reboot 0.1.1 → 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/CHANGELOG.md +9 -0
- data/README.md +60 -4
- data/lib/basic_loader.rb +1 -0
- data/lib/crypt_reboot/cli/params/definition.rb +6 -0
- data/lib/crypt_reboot/cli/params_parsing_executor.rb +6 -3
- data/lib/crypt_reboot/elastic_memory_locker.rb +42 -0
- data/lib/crypt_reboot/instantiable_config.rb +4 -1
- data/lib/crypt_reboot/safe_temp/directory.rb +1 -1
- data/lib/crypt_reboot/safe_temp/mounter.rb +4 -2
- data/lib/crypt_reboot/version.rb +1 -1
- data/lib/crypt_reboot.rb +1 -0
- metadata +3 -2
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/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -28,13 +28,16 @@ Debian, Ubuntu, Linux Mint, Pop!_OS, etc.
|
|
28
28
|
On the other hand, do not expect it to work on other distributions now.
|
29
29
|
But support for them may come in upcoming versions.
|
30
30
|
|
31
|
-
Following distributions were tested by the author:
|
31
|
+
Following distributions were tested by the author on the AMD64 machine:
|
32
|
+
- DappNode 0.2.75 is based on Debian 12, see below
|
33
|
+
- Debian 12 needs [symlinks for kernel and initramfs](#no-symlinks-to-most-recent-kernel-and-initramfs)
|
34
|
+
- Pop!_OS 22.04 LTS
|
35
|
+
- Ubuntu 23.04
|
32
36
|
- Ubuntu 22.04 LTS
|
33
37
|
- Ubuntu 20.04 LTS needs tiny adjustments to system settings,
|
34
38
|
specifically [changing compression](#lz4-initramfs-compression) and
|
35
39
|
[fixing systemd kexec support](#staged-kernel-not-being-executed-by-systemd)
|
36
40
|
- ~~Ubuntu 18.04 LTS~~ is not supported (initramfs uses *pre-crypttab* format)
|
37
|
-
- Pop!_OS 22.04 LTS
|
38
41
|
|
39
42
|
If you have successfully run cryptreboot on another distribution,
|
40
43
|
please contact me and I will update the list.
|
@@ -50,17 +53,36 @@ You need to ensure those are installed:
|
|
50
53
|
If you use recent, mainstream Linux distribution, other requirements are
|
51
54
|
probably already met:
|
52
55
|
- `kexec` support in the kernel
|
53
|
-
- `
|
56
|
+
- `ramfs` filesystem support in kernel
|
54
57
|
- `cryptsetup` (if you use disk encryption, it should be installed)
|
55
58
|
- `systemd` or another way to guarantee staged kernel is executed on reboot
|
56
59
|
- `strace` (not required if `--skip-lz4-check` flag is specified)
|
57
60
|
|
61
|
+
If you use Debian-based distribution, use this command to install required packages:
|
62
|
+
|
63
|
+
$ sudo apt install --no-install-recommends cryptsetup-initramfs kexec-tools ruby strace systemd
|
64
|
+
|
65
|
+
When asked if kexec should handle reboots, answer `yes` (however the answer probably
|
66
|
+
doesn't matter for cryptreboot to work).
|
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
|
+
|
58
76
|
## Installation
|
59
77
|
|
60
78
|
Make sure the required software is installed, then install the gem system-wide by executing:
|
61
79
|
|
62
80
|
$ sudo gem install crypt_reboot
|
63
81
|
|
82
|
+
To upgrade run:
|
83
|
+
|
84
|
+
$ sudo gem update crypt_reboot
|
85
|
+
|
64
86
|
## Usage
|
65
87
|
|
66
88
|
Cryptreboot performs operations normally only available to the root user,
|
@@ -74,7 +96,7 @@ To see the usage, run:
|
|
74
96
|
|
75
97
|
$ cryptreboot --help
|
76
98
|
|
77
|
-
##
|
99
|
+
## Troubleshooting
|
78
100
|
|
79
101
|
### LZ4 initramfs compression
|
80
102
|
|
@@ -130,6 +152,40 @@ To cancel the change, remove the file:
|
|
130
152
|
|
131
153
|
$ sudo rm /etc/systemd/system/systemd-kexec.service.d/override.conf
|
132
154
|
|
155
|
+
### No symlinks to the most recent kernel and initramfs
|
156
|
+
|
157
|
+
By default, cryptreboot looks for kernel in `/boot/vmlinuz` and for initramfs
|
158
|
+
in `/boot/initrd.img`. If those files are missing in your Linux distribution,
|
159
|
+
cryptreboot will fail, unless you use `--kernel` and `--initramfs` command line
|
160
|
+
options.
|
161
|
+
|
162
|
+
$ sudo cryptreboot --kernel /boot/vmlinuz-`uname -r` --initramfs /boot/initrd.img-`uname -r`
|
163
|
+
|
164
|
+
If you don't want to specify options every time you reboot, add symlinks to
|
165
|
+
the currently running kernel and initramfs:
|
166
|
+
|
167
|
+
$ cd /boot
|
168
|
+
$ sudo ln -sf vmlinuz-`uname -r` vmlinuz
|
169
|
+
$ sudo ln -sf initrd.img-`uname -r` initrd.img
|
170
|
+
|
171
|
+
Unfortunately, you need to rerun it after each kernel upgrade, otherwise,
|
172
|
+
cryptreboot is going to boot the old kernel.
|
173
|
+
Upcoming versions of cryptreboot will offer better solutions.
|
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
|
+
|
133
189
|
## Development
|
134
190
|
|
135
191
|
After checking out the repo, run `bundle install` to install
|
data/lib/basic_loader.rb
CHANGED
@@ -8,6 +8,7 @@ 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'
|
@@ -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'
|
@@ -7,7 +7,7 @@ module CryptReboot
|
|
7
7
|
def call(raw_params)
|
8
8
|
params = parser.call(raw_params)
|
9
9
|
handle_action_params!(params) or configure_and_exec(params)
|
10
|
-
rescue StandardError => e
|
10
|
+
rescue StandardError, Interrupt => e
|
11
11
|
raise if debug?
|
12
12
|
|
13
13
|
sad_exiter_class.new(error_message(e))
|
@@ -21,6 +21,7 @@ module CryptReboot
|
|
21
21
|
|
22
22
|
def configure_and_exec(params)
|
23
23
|
config_updater.call(**params)
|
24
|
+
locker.call
|
24
25
|
loader.call
|
25
26
|
rebooter
|
26
27
|
end
|
@@ -45,7 +46,7 @@ module CryptReboot
|
|
45
46
|
|
46
47
|
attr_reader :parser, :config_updater, :loader, :help_generator,
|
47
48
|
:version_string, :debug_checker, :rebooter,
|
48
|
-
:happy_exiter_class, :sad_exiter_class
|
49
|
+
:happy_exiter_class, :sad_exiter_class, :locker
|
49
50
|
|
50
51
|
# rubocop:disable Metrics/ParameterLists
|
51
52
|
def initialize(parser: Params::Parser.new,
|
@@ -56,7 +57,8 @@ module CryptReboot
|
|
56
57
|
debug_checker: LazyConfig.debug,
|
57
58
|
rebooter: Rebooter.new,
|
58
59
|
happy_exiter_class: HappyExiter,
|
59
|
-
sad_exiter_class: SadExiter
|
60
|
+
sad_exiter_class: SadExiter,
|
61
|
+
locker: ElasticMemoryLocker.new)
|
60
62
|
@parser = parser
|
61
63
|
@config_updater = config_updater
|
62
64
|
@loader = loader
|
@@ -66,6 +68,7 @@ module CryptReboot
|
|
66
68
|
@rebooter = rebooter
|
67
69
|
@happy_exiter_class = happy_exiter_class
|
68
70
|
@sad_exiter_class = sad_exiter_class
|
71
|
+
@locker = locker
|
69
72
|
end
|
70
73
|
# rubocop:enable Metrics/ParameterLists
|
71
74
|
end
|
@@ -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
|
@@ -4,7 +4,7 @@ require 'tmpdir'
|
|
4
4
|
|
5
5
|
module CryptReboot
|
6
6
|
module SafeTemp
|
7
|
-
# Create temporary directory, mounts
|
7
|
+
# Create temporary directory, mounts ramfs and yields tmp dir location.
|
8
8
|
# Make sure to cleanup afterwards.
|
9
9
|
class Directory
|
10
10
|
def call
|
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
module CryptReboot
|
4
4
|
module SafeTemp
|
5
|
-
# Mount
|
5
|
+
# Mount ramfs at the given mount point, yield and unmount.
|
6
|
+
# We don't want the contents of directory to be swapped,
|
7
|
+
# therefore ramfs is used instead of tmpfs.
|
6
8
|
class Mounter
|
7
9
|
def call(dir, &block)
|
8
10
|
mounter.call(dir)
|
@@ -21,7 +23,7 @@ module CryptReboot
|
|
21
23
|
|
22
24
|
def initialize(runner: Runner::NoResult.new,
|
23
25
|
mounter: lambda { |dir|
|
24
|
-
runner.call(Config.mount_path, '-t', '
|
26
|
+
runner.call(Config.mount_path, '-t', 'ramfs', '-o', 'mode=700', 'none', dir)
|
25
27
|
},
|
26
28
|
umounter: ->(dir) { runner.call(Config.umount_path, dir) })
|
27
29
|
@runner = runner
|
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
|
@@ -71,6 +71,7 @@ files:
|
|
71
71
|
- lib/crypt_reboot/crypt_tab/keyfile_locator.rb
|
72
72
|
- lib/crypt_reboot/crypt_tab/luks_to_plain_converter.rb
|
73
73
|
- lib/crypt_reboot/crypt_tab/serializer.rb
|
74
|
+
- lib/crypt_reboot/elastic_memory_locker.rb
|
74
75
|
- lib/crypt_reboot/files_generator.rb
|
75
76
|
- lib/crypt_reboot/files_writer.rb
|
76
77
|
- lib/crypt_reboot/gziper.rb
|