crypt_reboot 0.1.1 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ca95c9301674a1698f766dbfa5dfd06adc99e91a286c32b7eaa77d8611e21762
4
- data.tar.gz: 5403a4ed739f8b5901451e3e413598e85acfee1765266a66d85257c708904399
3
+ metadata.gz: 90456cf783f95d79186882a7fce00b153b4ff1928a68efd4609fb7e8859d3b04
4
+ data.tar.gz: d5fd15cb6705793a7e357666158eaa4f95f5c14d41b22b1d82d087a921fa512c
5
5
  SHA512:
6
- metadata.gz: d633a85afa5dc298f39c144d700347cb20ae4bc03e5865ba3a92c2a1ae0ec9bc679393b612f7c18838d35578f583db8f791aab223f896a1ed3fce8bcfd78c6e8
7
- data.tar.gz: 59442b7e7106a5d2892def87930503472315dbc45da8d9bf8919d29fc7fc998edcb2dfe69b3bc4ea0306c173bc1dc305fa5be42954bb706eb35f4104531933a3
6
+ metadata.gz: 5c99c3e114727a1236ef3dd9f536a56b1a89639c4447f6387ec5bcd1bd25234f2655a75f306ace56dd78c36a0aadf77da4321ed6626c36c63e38c9852fefefea
7
+ data.tar.gz: 37acfc427190670ad362cfb60a8a18ed29bcab338d24ac728ac23f4e3934c6669175db7872836ac46211d09dd16cba861259ec8e99c829050c1a8a3b875b9724
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## [0.1.2] - 2023-07-22
2
+
3
+ - Lock memory to prevent secrets leaking to swap
4
+ - Use `ramfs` instead of `tmpfs` for the same reason
5
+
6
+ ## [0.1.1] - 2023-07-13
7
+
8
+ - Standardize passphrase prompt
9
+
1
10
  ## [0.1.0] - 2023-07-09
2
11
 
3
12
  - Initial release
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,11 +53,18 @@ 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
- - `tmpfs` filesystem support in kernel
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
+
58
68
  ## Installation
59
69
 
60
70
  Make sure the required software is installed, then install the gem system-wide by executing:
@@ -130,6 +140,26 @@ To cancel the change, remove the file:
130
140
 
131
141
  $ sudo rm /etc/systemd/system/systemd-kexec.service.d/override.conf
132
142
 
143
+ ### No symlinks to most recent kernel and initramfs
144
+
145
+ By default cryptreboot looks for kernel in `/boot/vmlinuz` and for initramfs
146
+ in `/boot/initrd.img`. If those files are missing in your Linux distribution,
147
+ cryptreboot will fail, unless you use `--kernel` and `--initramfs` command line
148
+ options.
149
+
150
+ $ sudo cryptreboot --kernel /boot/vmlinuz-`uname -r` --initramfs /boot/initrd.img-`uname -r`
151
+
152
+ If you don't want to specify options every time you reboot, add symlinks to
153
+ the currently running kernel and initramfs:
154
+
155
+ $ cd /boot
156
+ $ sudo ln -sf vmlinuz-`uname -r` vmlinuz
157
+ $ sudo ln -sf initrd.img-`uname -r` initrd.img
158
+
159
+ Unfortunately, you need to rerun it after each kernel upgrade, otherwise,
160
+ cryptreboot is going to boot the old kernel.
161
+ Upcoming versions of cryptreboot will offer better solutions.
162
+
133
163
  ## Development
134
164
 
135
165
  After checking out the repo, run `bundle install` to install
data/lib/basic_loader.rb CHANGED
@@ -14,6 +14,7 @@ require 'crypt_reboot/gziper'
14
14
  require 'crypt_reboot/initramfs_patch_squeezer'
15
15
  require 'crypt_reboot/kexec_patching_loader'
16
16
  require 'crypt_reboot/lazy_config'
17
+ require 'crypt_reboot/memory_locker'
17
18
  require 'crypt_reboot/passphrase_asker'
18
19
  require 'crypt_reboot/patched_initramfs_generator'
19
20
  require 'crypt_reboot/rebooter'
@@ -5,9 +5,10 @@ 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
8
9
  params = parser.call(raw_params)
9
10
  handle_action_params!(params) or configure_and_exec(params)
10
- rescue StandardError => e
11
+ rescue StandardError, Interrupt => e
11
12
  raise if debug?
12
13
 
13
14
  sad_exiter_class.new(error_message(e))
@@ -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: MemoryLocker.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,33 @@
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
@@ -4,7 +4,7 @@ require 'tmpdir'
4
4
 
5
5
  module CryptReboot
6
6
  module SafeTemp
7
- # Create temporary directory, mounts tmpfs and yields tmp dir location.
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 tmpfs at the given mount point, yield and unmount
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', 'tmpfs', '-o', 'mode=700', 'none', dir)
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CryptReboot
4
- VERSION = '0.1.1'
4
+ VERSION = '0.1.2'
5
5
  end
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.1.1
4
+ version: 0.1.2
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-13 00:00:00.000000000 Z
11
+ date: 2023-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tty-command
@@ -38,6 +38,20 @@ 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
41
55
  description:
42
56
  email:
43
57
  - pepawel@users.noreply.github.com
@@ -93,6 +107,7 @@ files:
93
107
  - lib/crypt_reboot/luks/dumper/luks_v2_parser.rb
94
108
  - lib/crypt_reboot/luks/key_fetcher.rb
95
109
  - lib/crypt_reboot/luks/version_detector.rb
110
+ - lib/crypt_reboot/memory_locker.rb
96
111
  - lib/crypt_reboot/passphrase_asker.rb
97
112
  - lib/crypt_reboot/patched_initramfs_generator.rb
98
113
  - lib/crypt_reboot/rebooter.rb