Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

My previous question produced the commands to add an encrypted swap file:

# One-time setup:
fallocate -l 4G /root/swapfile.crypt
chmod 600 /root/swapfile.crypt

# On every boot:
loop=$(losetup -f)
losetup ${loop} /root/swapfile.crypt
cryptsetup open --type plain --key-file /dev/urandom ${loop} swapfile
mkswap /dev/mapper/swapfile
swapon /dev/mapper/swapfile

But Arch Linux uses systemd, and I'm having trouble figuring out how to best get systemd to activate my swap file automatically. systemd.swap suggests that I should have a dev-mapper-swapfile.swap unit that looks something like:

[Unit]
Description=Encrypted Swap File

[Swap]
What=/dev/mapper/swapfile

That would execute the swapon command. But I'm not sure how to execute the commands to prepare /dev/mapper/swapfile. I gather that dev-mapper-swapfile.swap should declare a dependency on some other unit, but I'm not sure what that unit should look like.

share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

You may want to have a look at:

  • crypttab(5)
  • systemd-cryptsetup@.service(8)
  • systemd-cryptsetup-generator(8)

Those work for encrypted volumes backed by block devices. They should also work for file backed volumes.

Update:

This does work for me:

# Automatically generated by systemd-cryptsetup-generator

[Unit]
Description=Cryptography Setup for %I
Documentation=man:systemd-cryptsetup@.service(8) man:crypttab(5)
SourcePath=/etc/crypttab
Conflicts=umount.target
DefaultDependencies=no
BindsTo=dev-mapper-%i.device
After=systemd-readahead-collect.service systemd-readahead-replay.service
Before=umount.target
Before=cryptsetup.target
After=systemd-random-seed-load.service

[Service]
Type=oneshot
RemainAfterExit=yes
TimeoutSec=0
ExecStart=/usr/lib/systemd/systemd-cryptsetup attach 'swap2' '/swap.test'     '/dev/urandom' 'swap'
ExecStop=/usr/lib/systemd/systemd-cryptsetup detach 'swap2'
ExecStartPost=/sbin/mkswap '/dev/mapper/swap2'

Steps to get this file:

  • Create an entry in /etc/crypttab: swap2 /swap.test /dev/urandom swap
  • Run this command: /usr/lib/systemd/system-generators/systemd-cryptsetup-generator This creates unit files in the /tmp/ directory.
  • Search for the generated unit file.
  • Open it and remove the entry swap.test.device from the After= and BindsTo= directives. This is important, as there is by definition no device for the swapfile. This prevents the start of the unitfile.
  • Copy the unitfile to /etc/systemd/system/
  • Activate it for your favourite target.
share|improve this answer
    
You may be right, but I don't understand how to apply those to a file backed volume. In particular, the /dev/loopN produced by losetup -f is not necessarily consistent between boots. –  cjm Feb 13 '13 at 17:14
    
cryptsetup itself should allocate the loopback device. cryptsetup open /swap.test swap. I couldn't get it to work when booting (using only /etc/crypttab). A unit which does everything itself with ExecStart directives should work. Maybe this should reported to systemd devs. –  t-8ch Feb 13 '13 at 17:54
    
I think the problem might be that it didn't execute mkswap. Because I'm using a random key, the swap file has to be reinitialized each boot. But I'm not sure how to set that up. –  cjm Feb 13 '13 at 19:34
add comment

Here's the end result I came up with based on t-8ch's answer.

Put this in /etc/systemd/system/systemd-cryptsetup@swapfile.service:

# Automatically generated by systemd-cryptsetup-generator
# then manually tweaked

[Unit]
Description=Cryptography Setup for %I
Documentation=man:systemd-cryptsetup@.service(8) man:crypttab(5)
SourcePath=/etc/crypttab
Conflicts=umount.target
DefaultDependencies=no
BindsTo=dev-mapper-%i.device
After=systemd-readahead-collect.service systemd-readahead-replay.service
Before=umount.target
Before=cryptsetup.target
After=systemd-random-seed-load.service

[Service]
Type=oneshot
RemainAfterExit=yes
TimeoutSec=0
ExecStart=/usr/lib/systemd/systemd-cryptsetup attach 'swapfile' '/root/swapfile.crypt' '/dev/urandom' 'swap,cipher=aes-cbc-essiv:sha256,size=256'
ExecStop=/usr/lib/systemd/systemd-cryptsetup detach 'swapfile'
ExecStartPost=/sbin/mkswap '/dev/mapper/swapfile'

Put this in /etc/systemd/system/dev-mapper-swapfile.swap:

[Unit]
Description=Encrypted Swap File
Requires=systemd-cryptsetup@swapfile.service
After=systemd-cryptsetup@swapfile.service
Before=swap.target

[Swap]
What=/dev/mapper/swapfile

[Install]
WantedBy=swap.target

One-time setup (as root) to create the swapfile, enable it for future boots, and start using it immediately:

fallocate -l 4G /root/swapfile.crypt
chmod 600 /root/swapfile.crypt
systemctl enable dev-mapper-swapfile.swap
systemctl start dev-mapper-swapfile.swap

The size in the fallocate command determines how big your swapfile will be.

The /etc/crypttab entry is not necessary; it's just a way to generate systemd-cryptsetup@swapfile.service. Once that's done, you don't need it anymore.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.