freydis 0.1.1 → 0.8.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
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +15 -0
- data/README.md +19 -26
- data/bin/freydis +87 -5
- data/freydis.gemspec +3 -4
- data/lib/freydis/config.rb +28 -18
- data/lib/freydis/cryptsetup.rb +3 -7
- data/lib/freydis/disk.rb +0 -0
- data/lib/freydis/disk_luks.rb +18 -12
- data/lib/freydis/error.rb +0 -1
- data/lib/freydis/guard.rb +12 -19
- data/lib/freydis/rsync.rb +26 -28
- data/lib/freydis/version.rb +1 -2
- data/lib/freydis.rb +1 -20
- data.tar.gz.sig +0 -0
- metadata +24 -28
- metadata.gz.sig +0 -0
- data/lib/freydis/options.rb +0 -90
- data/lib/freydis/secrets/archive.rb +0 -73
- data/lib/freydis/secrets/gpg.rb +0 -63
- data/lib/freydis/secrets.rb +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8609f817dc7fdbd37760c0f0a2afe0652a2eba1841a062c595d00c16806def93
|
4
|
+
data.tar.gz: 97393b88c28dfc4ac136dbdb73c8cb624142cc9928b318bff3abff20d6df7354
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b9c9fc5a32b2cc4e4af1227705e93c3c4030bbacfce9d756d6d8f968a86fa72f498c28c57bfdae71ec2ece5ffb39c383b76afb1921a5874963bbf6aadbba12d
|
7
|
+
data.tar.gz: f20fd09c1cb93e12e5d493e160a3f4515e032aaeebb1393fec44c04fc9b70740e0c8c7a76f73572a00e86e67e99f1013c9fbc680208df42bddf4853a1737bbf8
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
## 0.8.0, release 2024/09/17
|
2
|
+
* Drop support for gpg, use [sgpg](https://github.com/szorfein/sgpg) instead.
|
3
|
+
* New workflow (github gem)
|
4
|
+
* New option `--restore-at PATH` to change the default `/`.
|
5
|
+
* Option `--disk PATH` now require the full path (e.g: `/dev/sdx`), you can add yourself by-id, by-uuid, etc...
|
6
|
+
* User can customize what paths to include `--paths-add PATHS` or exclude `--paths-del PATHS`.
|
7
|
+
* Encrypted disk is no more default, use `--disk-encrypt` if need.
|
8
|
+
|
9
|
+
## 0.2.0, release 2023/10/23
|
10
|
+
* Define constant OPTIONS and ACTIONS
|
11
|
+
* Correct rsync options
|
12
|
+
* Can save gpg recipient in freydis.yaml
|
13
|
+
* Enhance output of freydis -L
|
14
|
+
* Move engine in Freydis::Main
|
15
|
+
|
1
16
|
## 0.1.1, release 2022/10/8
|
2
17
|
* Restore archive with sudo if permission are insufficient.
|
3
18
|
|
data/README.md
CHANGED
@@ -9,10 +9,10 @@
|
|
9
9
|
|
10
10
|
</div>
|
11
11
|
|
12
|
-
Backup and restore data on encrypted device.
|
12
|
+
Backup and restore data (on encrypted) device.
|
13
13
|
|
14
14
|
## Requirements
|
15
|
-
Freydis use `rsync` and `cryptsetup
|
15
|
+
Freydis use `rsync` and `cryptsetup`.
|
16
16
|
|
17
17
|
## Install freydis locally
|
18
18
|
|
@@ -25,45 +25,38 @@ Freydis use `rsync` and `cryptsetup` and optionnal `bsdtar`, `shred`, `gnupg`.
|
|
25
25
|
## Examples
|
26
26
|
|
27
27
|
#### 0x01 - Initialisation
|
28
|
-
First, you need
|
28
|
+
First, you need to configure freydis and optionnaly encrypt a device disk.
|
29
29
|
|
30
|
-
$ freydis --disk sdc --encrypt --save
|
30
|
+
$ freydis --disk /dev/sdc --encrypt --save
|
31
31
|
|
32
32
|
The config file will be created at `~/.config/freydis/freydis.yaml`.
|
33
33
|
|
34
34
|
```yaml
|
35
35
|
---
|
36
|
-
:disk: /dev/
|
37
|
-
:
|
36
|
+
:disk: '/dev/sdc'
|
37
|
+
:disk_is_encrypt: true
|
38
|
+
:gpg_recipient: ''
|
39
|
+
:backup_paths: []
|
40
|
+
:exclude_paths: []
|
41
|
+
:restore_at: '/'
|
38
42
|
```
|
39
43
|
|
40
|
-
+ disk: save the full path `by-id` for `sdc` here.
|
41
|
-
+ paths -> An Array which contain a list of absolute paths for backup.
|
42
|
-
|
43
44
|
#### 0x02 - First backup
|
44
45
|
Freydis will use `rsync`, all paths must be separated by a comma:
|
45
46
|
|
46
|
-
$ freydis --
|
47
|
+
$ freydis --paths-add /home,/etc --save
|
47
48
|
|
48
|
-
|
49
|
-
With `--disk` and `--paths-add` saved in the config file, you only need to write:
|
50
|
-
|
51
|
-
$ freydis --restore
|
49
|
+
You can also exclude some paths with `--paths-del`
|
52
50
|
|
53
|
-
|
51
|
+
$ freydis --paths-del ~/.cache,~/.npm --save
|
54
52
|
|
55
|
-
|
56
|
-
Freydis can store secrets ([GPG Key](https://www.gnupg.org/) and [pass](https://www.passwordstore.org/) directory for now) and restore them if need:
|
53
|
+
And backup
|
57
54
|
|
58
|
-
$ freydis --
|
59
|
-
$ freydis --gpg-recipient szorfein@protonmail.com --secrets-restore
|
55
|
+
$ freydis --backup
|
60
56
|
|
61
|
-
|
62
|
-
|
63
|
-
### Tips
|
64
|
-
If you lost the config file, `freydis` has made a copy on your device when you're done your first `--backup`:
|
57
|
+
#### 0x03 - Restore
|
58
|
+
With `--disk` and `--paths-add` saved in the config file, you only need to write:
|
65
59
|
|
66
|
-
$ freydis --
|
67
|
-
$ cp -a /mnt/freydis/home/user/.config/freydis ~/.config/
|
60
|
+
$ freydis --restore
|
68
61
|
|
69
|
-
|
62
|
+
Freydis will restore all files in `/` by default, use `--restore-at PATH` to change.
|
data/bin/freydis
CHANGED
@@ -1,10 +1,92 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'freydis'
|
5
|
+
require 'optparse'
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
7
|
+
# Load options from YAML
|
8
|
+
config = Freydis::Config.new
|
9
|
+
config.load
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
+
options = config.opts
|
12
|
+
|
13
|
+
# puts "config file #{options}"
|
14
|
+
|
15
|
+
OptionParser.new do |opts|
|
16
|
+
opts.banner = 'Usage: freydis.rb [options]'
|
17
|
+
opts.version = Freydis::VERSION
|
18
|
+
|
19
|
+
opts.on('--disk PATH', String,
|
20
|
+
'Use the disk e.g /dev/sdc.') do |disk|
|
21
|
+
puts "choosed disk #{disk}"
|
22
|
+
options[:disk] = Freydis::Guard.disk(disk)
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on('--disk-encrypt', 'If need to use cryptsetup to open disk.') do
|
26
|
+
options[:disk_is_encrypt] = true
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on('-p PATHS', '--paths-add PATHS', Array,
|
30
|
+
'Add absolute PATHS to backup, separate by \',\'.') do |paths|
|
31
|
+
paths.each do |p|
|
32
|
+
Freydis::Guard.path? p
|
33
|
+
|
34
|
+
puts p
|
35
|
+
options[:backup_paths] << p unless options[:backup_paths].include? p
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
opts.on('-d PATHS', '--paths-del PATHS', Array,
|
40
|
+
'Add absolute PATHS to exclude for the backup, separate by \',\'.') do |paths|
|
41
|
+
paths.each do |p|
|
42
|
+
Freydis::Guard.path? p
|
43
|
+
|
44
|
+
puts p
|
45
|
+
options[:exclude_paths] << p unless options[:exclude_paths].include? p
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
opts.on('-L', '--list-opts', 'List all options currently used.') do
|
50
|
+
puts options
|
51
|
+
end
|
52
|
+
|
53
|
+
opts.on('--restore-at PATH', 'Restore saved datas on your system, default is /.') do |path|
|
54
|
+
Freydis::Guard.path? path
|
55
|
+
|
56
|
+
options[:restore_at] = path
|
57
|
+
end
|
58
|
+
|
59
|
+
# Engines options
|
60
|
+
|
61
|
+
opts.on('-e', '--encrypt', 'Encrypt and format (ext4) your device.') do
|
62
|
+
Freydis::DiskLuks.encrypt(options)
|
63
|
+
end
|
64
|
+
|
65
|
+
opts.on('-o', '--open', 'Open and mount disk at /mnt/freydis.') do
|
66
|
+
Freydis::DiskLuks.open(options)
|
67
|
+
end
|
68
|
+
|
69
|
+
opts.on('-c', '--close', 'Umount (and close encrypted) disk.') do
|
70
|
+
Freydis::DiskLuks.close(options)
|
71
|
+
end
|
72
|
+
|
73
|
+
opts.on('-b', '--backup', 'Perform a backup.') do
|
74
|
+
Freydis::DiskLuks.open(options)
|
75
|
+
Freydis::Rsync.new(options).backup
|
76
|
+
Freydis::DiskLuks.close(options)
|
77
|
+
end
|
78
|
+
|
79
|
+
opts.on('-r', '--restore', 'Restore saved datas on your system.') do
|
80
|
+
Freydis::DiskLuks.open(options)
|
81
|
+
Freydis::Rsync.new(options).restore
|
82
|
+
Freydis::DiskLuks.close(options)
|
83
|
+
end
|
84
|
+
|
85
|
+
opts.on('-s', '--save', 'Save current arguments in the config file.') do
|
86
|
+
config.save(options)
|
87
|
+
end
|
88
|
+
end.parse!
|
89
|
+
|
90
|
+
puts
|
91
|
+
puts 'Bye !'
|
92
|
+
puts
|
data/freydis.gemspec
CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
|
|
22
22
|
'bug_tracker_uri' => 'https://github.com/szorfein/freydis/issues',
|
23
23
|
'changelog_uri' => 'https://github.com/szorfein/freydis/blob/main/CHANGELOG.md',
|
24
24
|
'source_code_uri' => 'https://github.com/szorfein/freydis',
|
25
|
-
'funding_uri' => 'https://patreon.com/szorfein'
|
25
|
+
'funding_uri' => 'https://patreon.com/szorfein'
|
26
26
|
}
|
27
27
|
|
28
28
|
s.files = Dir.glob('{lib,bin}/**/*', File::FNM_DOTMATCH).reject { |f| File.directory?(f) }
|
@@ -35,11 +35,10 @@ Gem::Specification.new do |s|
|
|
35
35
|
s.executables << 'freydis'
|
36
36
|
s.require_paths = ['lib']
|
37
37
|
|
38
|
-
s.cert_chain = ['certs/szorfein.pem']
|
39
|
-
s.signing_key = File.expand_path('~/.ssh/gem-private_key.pem')
|
38
|
+
# s.cert_chain = ['certs/szorfein.pem']
|
39
|
+
# s.signing_key = File.expand_path('~/.ssh/gem-private_key.pem')
|
40
40
|
|
41
41
|
s.required_ruby_version = '>= 2.6'
|
42
42
|
s.requirements << 'cryptsetup'
|
43
43
|
s.requirements << 'rsync'
|
44
44
|
end
|
45
|
-
|
data/lib/freydis/config.rb
CHANGED
@@ -6,39 +6,49 @@ require 'pathname'
|
|
6
6
|
require 'mods/msg'
|
7
7
|
|
8
8
|
module Freydis
|
9
|
+
# Loads/Save config variable from a yaml file
|
9
10
|
class Config
|
10
11
|
include Msg
|
11
|
-
|
12
|
-
attr_accessor :gpg_recipient, :disk, :paths
|
12
|
+
attr_reader :opts
|
13
13
|
|
14
14
|
def initialize
|
15
|
-
@cpath =
|
16
|
-
|
17
|
-
|
18
|
-
@
|
15
|
+
@cpath = ENV['XDG_CONFIG_HOME'] ?
|
16
|
+
"#{ENV['XDG_CONFIG_HOME']}/freydis/freydis.yaml" :
|
17
|
+
"#{ENV['HOME']}/.config/freydis/freydis.yaml"
|
18
|
+
@opts = {
|
19
|
+
disk: '',
|
20
|
+
disk_is_encrypt: false,
|
21
|
+
backup_paths: [],
|
22
|
+
exclude_paths: [],
|
23
|
+
restore_at: '/'
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def save(opts)
|
28
|
+
FileUtils.mkdir_p Pathname.new(@cpath).parent.to_s
|
29
|
+
load_opts(opts)
|
30
|
+
File.write @cpath, YAML.dump(@opts)
|
31
|
+
success "Saving options to #{@cpath}..."
|
19
32
|
end
|
20
33
|
|
21
34
|
def load
|
22
35
|
if File.exist? @cpath
|
23
36
|
info 'Loading config...'
|
24
|
-
|
25
|
-
@disk = data_load[:disk]
|
26
|
-
@gpg_recipient = data_load[:gpg_recipient]
|
27
|
-
@paths = data_load[:paths]
|
37
|
+
@opts = YAML.load_file @cpath
|
28
38
|
else
|
29
39
|
info "Creating config file #{@cpath}..."
|
30
40
|
save
|
31
41
|
end
|
32
42
|
end
|
33
43
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
44
|
+
private
|
45
|
+
|
46
|
+
def load_opts(args)
|
47
|
+
@opts[:disk] = args[:disk] || ''
|
48
|
+
@opts[:disk_is_encrypt] = args[:disk_is_encrypt] || false
|
49
|
+
@opts[:backup_paths] = args[:backup_paths] || []
|
50
|
+
@opts[:exclude_paths] = args[:exclude_paths] || []
|
51
|
+
@opts[:restore_at] = args[:restore_at] || '/'
|
42
52
|
end
|
43
53
|
end
|
44
54
|
end
|
data/lib/freydis/cryptsetup.rb
CHANGED
@@ -4,14 +4,13 @@ require 'mods/exec'
|
|
4
4
|
require 'mods/msg'
|
5
5
|
|
6
6
|
module Freydis
|
7
|
+
# Interact with cryptsetup from unix.
|
7
8
|
class Cryptsetup
|
8
9
|
include Exec
|
9
10
|
include Msg
|
10
11
|
|
11
|
-
def initialize
|
12
|
-
Guard.
|
13
|
-
|
14
|
-
@disk = Disk.new(CONFIG.disk).search_sdx
|
12
|
+
def initialize(disk)
|
13
|
+
@disk = Guard.disk(disk)
|
15
14
|
@mapper_name = 'freydis-encrypt'
|
16
15
|
@mountpoint = '/mnt/freydis'
|
17
16
|
end
|
@@ -27,7 +26,6 @@ module Freydis
|
|
27
26
|
end
|
28
27
|
|
29
28
|
def close
|
30
|
-
umount
|
31
29
|
if File.exist? "/dev/mapper/#{@mapper_name}"
|
32
30
|
x "cryptsetup -v close #{@mapper_name}"
|
33
31
|
else
|
@@ -46,8 +44,6 @@ module Freydis
|
|
46
44
|
x "mount -t ext4 /dev/mapper/#{@mapper_name} #{@mountpoint}"
|
47
45
|
end
|
48
46
|
|
49
|
-
protected
|
50
|
-
|
51
47
|
def umount
|
52
48
|
if mounted?
|
53
49
|
x "umount #{@mountpoint}"
|
data/lib/freydis/disk.rb
CHANGED
File without changes
|
data/lib/freydis/disk_luks.rb
CHANGED
@@ -3,31 +3,37 @@
|
|
3
3
|
require 'mods/msg'
|
4
4
|
|
5
5
|
module Freydis
|
6
|
+
# Open, close a device disk (located at /dev)
|
6
7
|
module DiskLuks
|
7
8
|
extend Msg
|
9
|
+
|
8
10
|
module_function
|
9
11
|
|
10
|
-
def encrypt
|
11
|
-
cryptsetup =
|
12
|
+
def encrypt(opts)
|
13
|
+
cryptsetup = Cryptsetup.new(opts[:disk])
|
12
14
|
cryptsetup.encrypt
|
15
|
+
opts[:disk_is_encrypt] = true
|
13
16
|
cryptsetup.open
|
14
17
|
cryptsetup.format
|
15
18
|
cryptsetup.close
|
16
|
-
success "Disk #{
|
19
|
+
success "Disk #{opts[:disk]} fully encrypted."
|
17
20
|
end
|
18
21
|
|
19
|
-
def open
|
20
|
-
cryptsetup =
|
21
|
-
|
22
|
-
|
22
|
+
def open(opts)
|
23
|
+
cryptsetup = Cryptsetup.new(opts[:disk])
|
24
|
+
if opts[:disk_is_encrypt]
|
25
|
+
cryptsetup.close
|
26
|
+
cryptsetup.open
|
27
|
+
end
|
23
28
|
cryptsetup.mount
|
24
|
-
success "Disk #{
|
29
|
+
success "Disk #{opts[:disk]} opened."
|
25
30
|
end
|
26
31
|
|
27
|
-
def close
|
28
|
-
cryptsetup =
|
29
|
-
cryptsetup.
|
30
|
-
|
32
|
+
def close(opts)
|
33
|
+
cryptsetup = Cryptsetup.new(opts[:disk])
|
34
|
+
cryptsetup.umount
|
35
|
+
cryptsetup.close if opts[:disk_is_encrypt]
|
36
|
+
success "Disk #{opts[:disk]} closed."
|
31
37
|
end
|
32
38
|
end
|
33
39
|
end
|
data/lib/freydis/error.rb
CHANGED
data/lib/freydis/guard.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Freydis
|
4
|
+
# Guard control argument/path/input and quit if no valid
|
4
5
|
module Guard
|
5
6
|
module_function
|
6
7
|
|
7
8
|
def disk(name)
|
8
|
-
|
9
|
-
raise Freydis::InvalidDisk, 'No disk, use with
|
10
|
-
raise Freydis::InvalidDisk,
|
11
|
-
|
12
|
-
|
13
|
-
Freydis::Disk.new(full_path).search_id # return disk(name) by-id
|
9
|
+
raise Freydis::InvalidDisk, 'No disk, use with --disk PATH.' unless name
|
10
|
+
raise Freydis::InvalidDisk, 'No disk, use with --disk PATH.' if name == ''
|
11
|
+
raise Freydis::InvalidDisk, "No disk #{name} available." unless File.exist? name
|
12
|
+
|
13
|
+
name
|
14
14
|
rescue Freydis::InvalidDisk => e
|
15
15
|
puts "#{e.class} => #{e}"
|
16
16
|
exit 1
|
@@ -23,11 +23,12 @@ module Freydis
|
|
23
23
|
exit 1
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
27
|
-
raise Freydis::InvalidLuksDev,
|
26
|
+
def luks?(disk)
|
27
|
+
raise Freydis::InvalidLuksDev, 'No disk, use with --disk PATH.' unless disk
|
28
28
|
raise Freydis::InvalidLuksDev, "#{disk} does not exist." unless File.exist? disk
|
29
|
+
|
29
30
|
sudo = Process.uid != 0 ? 'sudo' : ''
|
30
|
-
|
31
|
+
unless system(sudo, 'cryptsetup', 'isLuks', disk)
|
31
32
|
raise Freydis::InvalidLuksDev, "#{disk} is not valid Luks device."
|
32
33
|
end
|
33
34
|
rescue Freydis::InvalidLuksDev => e
|
@@ -35,19 +36,11 @@ module Freydis
|
|
35
36
|
exit 1
|
36
37
|
end
|
37
38
|
|
38
|
-
def path?(
|
39
|
-
raise Freydis::InvalidPath, "#{
|
39
|
+
def path?(path)
|
40
|
+
raise Freydis::InvalidPath, "#{path} does not exist." unless File.exist? path
|
40
41
|
rescue Freydis::InvalidPath => e
|
41
42
|
puts "#{e.class} => #{e}"
|
42
43
|
exit 1
|
43
44
|
end
|
44
|
-
|
45
|
-
def gpg(recipient)
|
46
|
-
raise Freydis::GPG, "No recipient, use --gpg-recipient NAME" unless recipient
|
47
|
-
recipient
|
48
|
-
rescue Freydis::GPG => e
|
49
|
-
puts "#{e.class} => #{e}"
|
50
|
-
exit 1
|
51
|
-
end
|
52
45
|
end
|
53
46
|
end
|
data/lib/freydis/rsync.rb
CHANGED
@@ -3,45 +3,43 @@
|
|
3
3
|
require 'mods/exec'
|
4
4
|
|
5
5
|
module Freydis
|
6
|
+
# Interact with rsync from unix
|
6
7
|
class Rsync
|
7
8
|
include Exec
|
8
9
|
|
9
|
-
def initialize
|
10
|
-
@workdir = '/mnt/freydis/backup
|
11
|
-
@exclude_paths = %w[
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
/home/*/.gvfs
|
21
|
-
/home/*/.thumbnails/*
|
22
|
-
/home/*/.cache/*
|
23
|
-
/home/*/.local/share/*
|
24
|
-
/home/*/.Xauthority
|
25
|
-
/home/*/.xsession-errors
|
26
|
-
/lost+found
|
27
|
-
]
|
28
|
-
@opts = '-aAXHvRx'
|
10
|
+
def initialize(opts)
|
11
|
+
@workdir = '/mnt/freydis/backup'
|
12
|
+
@exclude_paths = %w['/dev/*' '/proc/*'
|
13
|
+
'/sys/*' '/tmp/*'
|
14
|
+
'/run/*' '/mnt/*'
|
15
|
+
'/media/*' '/home/*/.gvfs'
|
16
|
+
'/var/lib/dhcpcd/*' '*lost+found']
|
17
|
+
@backup = opts[:backup_paths] || []
|
18
|
+
@user_excludes = opts[:exclude_paths] || []
|
19
|
+
@restore_at = opts[:restore_at] || '/'
|
20
|
+
@opts = '-aAXHv --relative -hh'
|
29
21
|
end
|
30
22
|
|
31
23
|
def backup
|
32
|
-
|
24
|
+
raise 'Nothing to backup, use --paths-add PATH' if @backup == []
|
25
|
+
|
33
26
|
mkdir @workdir
|
34
|
-
exil =
|
35
|
-
save =
|
36
|
-
@opts += ' --delete'
|
27
|
+
exil = combine_exclude
|
28
|
+
save = @backup * ' '
|
29
|
+
@opts += ' --delete --recursive'
|
37
30
|
x "rsync #{@opts} --exclude={#{exil}} #{save} #{@workdir}"
|
38
|
-
|
31
|
+
puts "Saved path #{save}"
|
39
32
|
end
|
40
33
|
|
41
34
|
def restore
|
42
|
-
|
43
|
-
|
44
|
-
|
35
|
+
x "rsync #{@opts} #{@workdir} #{@restore_at}"
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def combine_exclude
|
41
|
+
new_array = @exclude_paths << @user_excludes
|
42
|
+
new_array.flatten! * ','
|
45
43
|
end
|
46
44
|
end
|
47
45
|
end
|
data/lib/freydis/version.rb
CHANGED
data/lib/freydis.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'freydis/version'
|
4
|
-
require_relative 'freydis/options'
|
5
4
|
require_relative 'freydis/config'
|
6
5
|
require_relative 'freydis/disk'
|
7
6
|
require_relative 'freydis/disk_luks'
|
@@ -9,25 +8,7 @@ require_relative 'freydis/cryptsetup'
|
|
9
8
|
require_relative 'freydis/rsync'
|
10
9
|
require_relative 'freydis/error'
|
11
10
|
require_relative 'freydis/guard'
|
12
|
-
require_relative 'freydis/secrets'
|
13
11
|
|
12
|
+
# Freydis - tool to backup data using rsync, cryptsetup.
|
14
13
|
module Freydis
|
15
|
-
CONFIG = Config.new
|
16
|
-
CONFIG.load
|
17
|
-
|
18
|
-
class Main
|
19
|
-
def initialize(args)
|
20
|
-
@argv = args[:argv]
|
21
|
-
end
|
22
|
-
|
23
|
-
def start
|
24
|
-
Options.new(@argv)
|
25
|
-
end
|
26
|
-
|
27
|
-
def bye
|
28
|
-
puts
|
29
|
-
puts "Bye !"
|
30
|
-
exit
|
31
|
-
end
|
32
|
-
end
|
33
14
|
end
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: freydis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- szorfein
|
@@ -12,31 +12,31 @@ cert_chain:
|
|
12
12
|
-----BEGIN CERTIFICATE-----
|
13
13
|
MIIEhTCCAu2gAwIBAgIBATANBgkqhkiG9w0BAQsFADBEMREwDwYDVQQDDAhzem9y
|
14
14
|
ZmVpbjEaMBgGCgmSJomT8ixkARkWCnByb3Rvbm1haWwxEzARBgoJkiaJk/IsZAEZ
|
15
|
-
|
15
|
+
FgNjb20wHhcNMjMxMDIzMTcyMTA4WhcNMjQxMDIyMTcyMTA4WjBEMREwDwYDVQQD
|
16
16
|
DAhzem9yZmVpbjEaMBgGCgmSJomT8ixkARkWCnByb3Rvbm1haWwxEzARBgoJkiaJ
|
17
|
-
k/
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
AaOBgTB/
|
27
|
-
|
17
|
+
k/IsZAEZFgNjb20wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCqe1yx
|
18
|
+
EG2oM25jeHp08A8zkaDNmbI3MujjrRM/WPEYZX2dVwOxkIS20hQVuxcAsBBA4W/W
|
19
|
+
kuPbqRkvLboaGaxLrllkSEJw9HA/GesTdXLyCFYmNzSFqGh5BafNSkxoiDhTavxp
|
20
|
+
xvYzAkYR/3CzSOWSxJk73wIg+F7w/nWJPTt2tgJE9hgR8uuFY+EzPOlFZhkFTdCV
|
21
|
+
88sBGuZPMjq7ASQVBE3UA+Y1xJeXE3/FhIhYvLnjevkkDLSLFmox0ZQf6nx6abuL
|
22
|
+
KTOGRA1bfLfkW5HMh5X5JwViliwG3RWhqAukJUgHTUk+oKtejlzSDqupwOenKZf0
|
23
|
+
xI2/BnS8zOsS6Te08iLxqZfI/lsG8wcPduekSetRI4VIOZ5QoRK54PiQjrOBhbnD
|
24
|
+
OQBB/XF1C80imZtRtdUqh6bK9WeWI4RYZ2/KwXL1AScEbXkBkkOECWoVrD18WgRm
|
25
|
+
siuX6RkNIelhtb0En7f3bizgPqlO0qPQV+wPi9TSBxdVG12C0OmjCQYMQD0CAwEA
|
26
|
+
AaOBgTB/MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBTlKnQ3qMUF
|
27
|
+
zydvZaKwdP+dnj2uajAiBgNVHREEGzAZgRdzem9yZmVpbkBwcm90b25tYWlsLmNv
|
28
28
|
bTAiBgNVHRIEGzAZgRdzem9yZmVpbkBwcm90b25tYWlsLmNvbTANBgkqhkiG9w0B
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
29
|
+
AQsFAAOCAYEAFjnBWWfaMeA8hP0Q76WmBCFckGN5I42X5RQkVYRRXIaeXIS1td/t
|
30
|
+
O1v1iQLo6ABfASMi6We7T16+ita68xwNOmSkMNHHXBr/fdGbHExxFSX7BXNRbwla
|
31
|
+
SS6Vy0bXKMDJbXcvkrmIolpYhEFm1218FCRCT6ogM1oWAJAfhfF9pMeRxrxjQYFn
|
32
|
+
ko8XgjIHxb83miOILgdq/lgJ4gfD7PsGfJtLCLiCKCcxIb4TtmKAzRwCDVpb6wqM
|
33
|
+
5xJZffAmHI7v8lVer53sPzm3INPu5xFZyfZ/SXYXPKKwln0efH63K5vuXYwEN7NI
|
34
|
+
SBSRTN03Hb65t86m6/r084SrNnLntQjCSqApzFBt1QwJ5cmiVilODN4V7y2hZpyK
|
35
|
+
hSk3b2VOotDPiWIm1p/IPXQDfm5x67Z5fJQPAlBTsse4jKyVyW1lZLmERSBuRZ2O
|
36
|
+
urXgRIzALxd/xazPCnoLSXPzfJSI6Y77S1EBvhPd9RaSO8IyH9RhPDP9mnTvW2Kl
|
37
|
+
NAUnoL+txK5a
|
38
38
|
-----END CERTIFICATE-----
|
39
|
-
date:
|
39
|
+
date: 2024-09-17 00:00:00.000000000 Z
|
40
40
|
dependencies: []
|
41
41
|
description: 'Freydis is a CLI tool to encrypt a disk device, backup and restore easyly.
|
42
42
|
Freydis use `cryptsetup` and `rsync` mainly.
|
@@ -60,11 +60,7 @@ files:
|
|
60
60
|
- lib/freydis/disk_luks.rb
|
61
61
|
- lib/freydis/error.rb
|
62
62
|
- lib/freydis/guard.rb
|
63
|
-
- lib/freydis/options.rb
|
64
63
|
- lib/freydis/rsync.rb
|
65
|
-
- lib/freydis/secrets.rb
|
66
|
-
- lib/freydis/secrets/archive.rb
|
67
|
-
- lib/freydis/secrets/gpg.rb
|
68
64
|
- lib/freydis/version.rb
|
69
65
|
- lib/mods/exec.rb
|
70
66
|
- lib/mods/msg.rb
|
@@ -93,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
89
|
requirements:
|
94
90
|
- cryptsetup
|
95
91
|
- rsync
|
96
|
-
rubygems_version: 3.3.
|
92
|
+
rubygems_version: 3.3.25
|
97
93
|
signing_key:
|
98
94
|
specification_version: 4
|
99
95
|
summary: Backup and Restore data from encrypted device.
|
metadata.gz.sig
CHANGED
Binary file
|
data/lib/freydis/options.rb
DELETED
@@ -1,90 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'optparse'
|
4
|
-
|
5
|
-
module Freydis
|
6
|
-
class Options
|
7
|
-
def initialize(argv)
|
8
|
-
parse(argv)
|
9
|
-
end
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
def parse(argv)
|
14
|
-
OptionParser.new do |opts|
|
15
|
-
opts.banner = 'Usage: freydis.rb [options]'
|
16
|
-
opts.version = VERSION
|
17
|
-
|
18
|
-
opts.on('--disk NAME', /^sd[a-z]$/, 'Use the disk NAME (e.g: sda, sdb).') do |disk|
|
19
|
-
Freydis::CONFIG.disk = Guard.disk(disk)
|
20
|
-
end
|
21
|
-
|
22
|
-
opts.on('--gpg-recipient NAME', String, 'Use gpg key NAME.') do |key|
|
23
|
-
Freydis::CONFIG.gpg_recipient = Guard.gpg(key)
|
24
|
-
end
|
25
|
-
|
26
|
-
opts.on('-p PATHS', '--paths-add PATHS', Array, 'Add absolute PATHS to the backup list.') do |paths|
|
27
|
-
paths.each do |p|
|
28
|
-
Freydis::Guard.path? p
|
29
|
-
Freydis::CONFIG.paths << p
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
opts.on('-d PATH', '--path-del PATH', String, 'Remove absolute PATH from the backup list.') do |p|
|
35
|
-
Freydis::Guard.path? p
|
36
|
-
Freydis::CONFIG.paths.delete p if CONFIG.paths.include? p
|
37
|
-
end
|
38
|
-
|
39
|
-
opts.on('-L', '--paths-list', 'List all paths from your list.') do
|
40
|
-
if Freydis::CONFIG.paths.nil?
|
41
|
-
puts 'Nothing in paths yet...'
|
42
|
-
else
|
43
|
-
puts Freydis::CONFIG.paths
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# Engines options
|
48
|
-
|
49
|
-
opts.on('-e', '--encrypt', 'Encrypt and format (ext4) your device.') do
|
50
|
-
Freydis::DiskLuks.encrypt
|
51
|
-
end
|
52
|
-
|
53
|
-
opts.on('-o', '--open', 'Open and mount encrypted disk at /mnt/freydis.') do
|
54
|
-
Freydis::DiskLuks.open
|
55
|
-
end
|
56
|
-
|
57
|
-
opts.on('-c', '--close', 'Umount and close encrypted disk.') do
|
58
|
-
Freydis::DiskLuks.close
|
59
|
-
end
|
60
|
-
|
61
|
-
opts.on('-b', '--backup', 'Perform a backup.') do
|
62
|
-
Freydis::Rsync.new.backup
|
63
|
-
end
|
64
|
-
|
65
|
-
opts.on('-r', '--restore', 'Restore saved datas on your system.') do
|
66
|
-
Freydis::Rsync.new.restore
|
67
|
-
end
|
68
|
-
|
69
|
-
opts.on('--secrets-backup', 'Backup only secrets, including GPG keys.') do |s|
|
70
|
-
Freydis::Secrets.backup
|
71
|
-
end
|
72
|
-
|
73
|
-
opts.on('--secrets-restore', 'Restore secrets.') do |s|
|
74
|
-
Freydis::Secrets.restore
|
75
|
-
end
|
76
|
-
|
77
|
-
opts.on('-s', '--save', 'Save current arguments in the config file.') do
|
78
|
-
Freydis::CONFIG.save
|
79
|
-
end
|
80
|
-
|
81
|
-
begin
|
82
|
-
opts.parse!(argv)
|
83
|
-
rescue OptionParser::ParseError => e
|
84
|
-
warn e.message, "\n", opts
|
85
|
-
exit 1
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'date'
|
4
|
-
require 'fileutils'
|
5
|
-
|
6
|
-
module Freydis
|
7
|
-
module Secrets
|
8
|
-
# Create or Restore an archive of secrets with bsdtar
|
9
|
-
class Archive
|
10
|
-
include Exec
|
11
|
-
include Msg
|
12
|
-
|
13
|
-
def initialize(gpg)
|
14
|
-
@workdir = '/mnt/freydis/secrets'
|
15
|
-
@filename = "#{@workdir}/#{CONFIG.gpg_recipient}_#{Date.today}.tar.gz"
|
16
|
-
@restore_dir = '/tmp'
|
17
|
-
@include_paths = %w[]
|
18
|
-
@gpg = gpg
|
19
|
-
end
|
20
|
-
|
21
|
-
def create
|
22
|
-
populate_include
|
23
|
-
inc_paths = @include_paths * ' '
|
24
|
-
|
25
|
-
mkdir @workdir
|
26
|
-
info "Creating archive #{@filename}..."
|
27
|
-
bsdtar "--acls --xattrs -cpvf #{@filename} #{inc_paths}"
|
28
|
-
@gpg.clean_keys
|
29
|
-
end
|
30
|
-
|
31
|
-
# Restore the most recent archive in your $HOME
|
32
|
-
def restore
|
33
|
-
last_archive = find_last_archive
|
34
|
-
error 'No archive found.' unless last_archive
|
35
|
-
|
36
|
-
mkdir @restore_dir
|
37
|
-
info "Restoring #{last_archive}..."
|
38
|
-
bsdtar "-xvf #{last_archive} -C #{@restore_dir}"
|
39
|
-
@gpg.import_keys @restore_dir
|
40
|
-
@gpg.clean_keys @restore_dir
|
41
|
-
end
|
42
|
-
|
43
|
-
protected
|
44
|
-
|
45
|
-
def populate_include
|
46
|
-
@gpg.export_keys unless File.exist? @gpg.seckey_path
|
47
|
-
search_paths(%W[#{ENV['HOME']}/.password-store
|
48
|
-
#{@gpg.seckey_path}
|
49
|
-
#{@gpg.pubkey_path}])
|
50
|
-
end
|
51
|
-
|
52
|
-
def find_last_archive
|
53
|
-
if Process.uid == 0
|
54
|
-
Dir.glob("#{@workdir}/#{CONFIG.gpg_recipient}*").sort[0]
|
55
|
-
else
|
56
|
-
archive = `sudo ls #{@workdir}/ | grep #{CONFIG.gpg_recipient} | sort | head -1`.chomp
|
57
|
-
"#{@workdir}/#{archive}" if archive
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
def search_paths(paths)
|
64
|
-
paths.each do |p|
|
65
|
-
if Dir.exist?(p) || File.exist?(p)
|
66
|
-
info "Found #{p}, add to archive..."
|
67
|
-
@include_paths << p
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
data/lib/freydis/secrets/gpg.rb
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Freydis
|
4
|
-
module Secrets
|
5
|
-
class GPG
|
6
|
-
include Exec
|
7
|
-
include Msg
|
8
|
-
|
9
|
-
attr_reader :seckey_path, :pubkey_path
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
@recipient = Guard.gpg(CONFIG.gpg_recipient)
|
13
|
-
@seckey_path = "/tmp/#{@recipient}-secret.key"
|
14
|
-
@pubkey_path = "/tmp/#{@recipient}-public.key"
|
15
|
-
end
|
16
|
-
|
17
|
-
def export_keys
|
18
|
-
info "Exporting keys for #{@recipient}..."
|
19
|
-
gpg "-a --export-secret-keys --armor #{@recipient} >#{@seckey_path}"
|
20
|
-
gpg "-a --export --armor #{@recipient} >#{@pubkey_path}"
|
21
|
-
end
|
22
|
-
|
23
|
-
def import_keys(prefix = nil)
|
24
|
-
is_key = `gpg -K | grep #{@recipient}`.chomp
|
25
|
-
if is_key.empty?
|
26
|
-
info "Importing key #{@recipient}..."
|
27
|
-
gpg_import(prefix)
|
28
|
-
else
|
29
|
-
info "Key #{@recipient} is alrealy present, skip import."
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def clean_keys(prefix = nil)
|
34
|
-
if prefix
|
35
|
-
shred "#{prefix}#{@seckey_path}", "#{prefix}#{@pubkey_path}"
|
36
|
-
else
|
37
|
-
shred @seckey_path, @pubkey_path
|
38
|
-
end
|
39
|
-
success "Clean keys."
|
40
|
-
end
|
41
|
-
|
42
|
-
protected
|
43
|
-
|
44
|
-
def gpg_import(prefix)
|
45
|
-
if prefix
|
46
|
-
gpg "--armor --import #{prefix}#{@seckey_path}"
|
47
|
-
gpg "--armor --import #{prefix}#{@pubkey_path}"
|
48
|
-
else
|
49
|
-
gpg "--armor --import #{@seckey_path}"
|
50
|
-
gpg "--armor --import #{@pubkey_path}"
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
def gpg(command)
|
57
|
-
unless system("gpg #{command}")
|
58
|
-
error "Exe: gpg #{command}"
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
data/lib/freydis/secrets.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'mods/msg'
|
4
|
-
require_relative 'secrets/gpg'
|
5
|
-
require_relative 'secrets/archive'
|
6
|
-
|
7
|
-
module Freydis
|
8
|
-
module Secrets
|
9
|
-
extend Msg
|
10
|
-
|
11
|
-
def self.backup
|
12
|
-
DiskLuks.open
|
13
|
-
info 'Backup secrets...'
|
14
|
-
gpg = GPG.new
|
15
|
-
archive = Archive.new(gpg)
|
16
|
-
archive.create
|
17
|
-
DiskLuks.close
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.restore
|
21
|
-
DiskLuks.open
|
22
|
-
info 'Restoring secrets...'
|
23
|
-
gpg = GPG.new
|
24
|
-
archive = Archive.new(gpg)
|
25
|
-
archive.restore
|
26
|
-
DiskLuks.close
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|