crypt_reboot 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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