google / fscrypt

Go tool for managing Linux filesystem encryption
Apache License 2.0
876 stars 97 forks source link

A question: how does diectory know what policy protects it? #395

Closed ardabro closed 7 months ago

ardabro commented 7 months ago

I realized that a policy does not store any information about directories protected by it. On the other hand, fscrypt knows what is the policy designated for a given directory. I don't see any hidden files in the directory. So my question: where is stored the connection between a directory and the policy designated for it? Shouldn't this key information be added to the readme?

ebiggers commented 7 months ago

So my question: where is stored the connection between a directory and the policy designated for it?

It's in a hidden extended attribute of the directory.

Shouldn't this key information be added to the readme?

It's necessary to make decisions about what to include in the readme and what to leave out; otherwise it would get too long. I don't see this information as being particularly useful for users of the fscrypt tool; it's an implementation detail. It's mentioned in the kernel documentation, which is the place to go if you want more details about how native Linux filesystem encryption works, regardless of which userspace tool is used to set it up.

ardabro commented 7 months ago

Ok, I see. Thanks. But how can I list such attributes from CLI? I see xattr shows nothing... (ext4) getfattr also shows nothing...

ebiggers commented 7 months ago

It's a hidden xattr. The information in it is retrievable via ioctls, not via the xattr system calls.

What problem are you trying to solve? If you're using the fscrypt tool and you want to see what policy protects a directory, just use fscrypt status DIR. There are examples of this in the readme already.

ardabro commented 7 months ago

I'm just trying to understand how it works. Anyway - it isn't so important. The more important question I have now is how this engine knows what to mount at login since login protector doesn't know what they protect? Is there a list of directories to auto mount per user? I created regular encrypted directory; then I created login protector and attached it to the policy. fscrypt status / and fscrypt status /mnt/x look good PAM scripts are configured. But nothing is mounted at startup. How can I debug this?

Dec 07 22:54:40 hebel2 pam_fscrypt[1377]: found ext4 filesystem "/" (/dev/nvme0n1p5)
Dec 07 22:54:40 hebel2 pam_fscrypt[1377]: listing protectors in "/.fscrypt/protectors"
Dec 07 22:54:40 hebel2 pam_fscrypt[1377]: found 1 protectors
Dec 07 22:54:40 hebel2 pam_fscrypt[1377]: successfully read metadata from "/.fscrypt/protectors/eea0f2fb1a0cec88"
Dec 07 22:54:40 hebel2 pam_fscrypt[1377]: Getting protector eea0f2fb1a0cec88 from option
Dec 07 22:54:40 hebel2 pam_fscrypt[1377]: copying AUTHTOK for use in the session open
Dec 07 22:54:40 hebel2 pam_fscrypt[1377]: Setting euid=0 egid=0 groups=[]
Dec 07 22:54:40 hebel2 pam_fscrypt[1377]: Current privs (real, effective): uid=(0,0) gid=(0,0) groups=[]
Dec 07 22:54:40 hebel2 pam_fscrypt[1377]: Authenticate(map[debug:true]) succeeded
Dec 07 22:54:40 hebel2 lightdm[1377]: gkr-pam: unable to locate daemon control file       <--- ?????
Dec 07 22:54:40 hebel2 lightdm[1377]: gkr-pam: stashed password to try later in open session
ebiggers commented 7 months ago

pam_fscrypt finds all the policies (stored in .fscrypt/policies directories at the root of filesystems) that are protected by the user's login protector and unlocks them. That automatically unlocks the directories that are protected by those policies. There is no "mounting" involved, as native filesystem encryption is used.

Have you read https://github.com/google/fscrypt#directories-using-my-login-passphrase-are-not-automatically-unlocking?

ardabro commented 7 months ago

Have you read https://github.com/google/fscrypt#directories-using-my-login-passphrase-are-not-automatically-unlocking?

Yes. PAM is configured. Actually seems that fscrypt installation on Debian (regular, bookworm) did it automatically. Anyway I rechecked it according to the manual. My password never changed and password set initially for login protector is exactly the same. I'm not trying to login via ssh. ssh server isn't started at all. fscrypt is enabled. I'm able to unlock manually using any: "custom" or "login" protector. According to system log /mnt/x is mounted (it is in fstab) before pam_fscrypt events appear. Is there anything useful I can try to find in the logs in this situation?

> sudo fscrypt status /mnt/x
ext4 filesystem "/mnt/x" has 2 protectors and 2 policies.
Only root can create fscrypt metadata on this filesystem.

PROTECTOR         LINKED   DESCRIPTION
eea0f2fb1a0cec88  Yes (/)  login protector for ardabro
cf54c4258449a070  No       custom protector "ardabro_home"

POLICY                            UNLOCKED  PROTECTORS
84b0de269f695da9d00df84385735580  No        cf54c4258449a070
914c59715883a5987d5123a41a7260f4  Yes       cf54c4258449a070, eea0f2fb1a0cec88

In above example it was unlocked manually

/etc/pam.d/common-auth (without comments):

auth    [success=1 default=ignore]  pam_unix.so nullok
auth    requisite           pam_deny.so
auth    required            pam_permit.so
auth    optional    pam_fscrypt.so debug
auth    required    pam_ecryptfs.so unwrap

/etc/pam.d/common-password (without comments):

password    [success=1 default=ignore]  pam_unix.so obscure yescrypt
password    requisite           pam_deny.so
password    required            pam_permit.so
password    optional    pam_fscrypt.so 
password    optional    pam_gnome_keyring.so 
password    optional    pam_ecryptfs.so 

/etc/pam.d/common-session (without comments):

session [default=1]         pam_permit.so
session requisite           pam_deny.so
session required            pam_permit.so
session required    pam_unix.so 
session optional    pam_fscrypt.so 
session optional    pam_systemd.so 
session optional    pam_ecryptfs.so unwrap
ebiggers commented 7 months ago

Can you add debug to all instances of pam_fscrypt.so, not just the one in /etc/pam.d/common-auth, and check the log after that? The snippet of the log you posted did not include OpenSession, which is the part that actually does the unlocking.

ardabro commented 7 months ago

Thanks for this hint. It turned out, that my policies were readable for root only. Now it works like a harm. Wonderful! Is there any particular reason that policies are readable for root only? I'm not sure what is better now: add read flags for everyone or change owner to me.

ebiggers commented 7 months ago

If the policies are for a particular user, they should be owned by that user. How did you create these policies? If you run fscrypt encrypt and specify a user's login protector, fscrypt makes the new policy be owned by the user of the login protector. Old versions of fscrypt behaved a bit differently though. Which version are you using?

ardabro commented 7 months ago

I use v0.3.3 from Debian repo. I created everything manually: first policy creation, then encryption. One more doubt: when protector's passphrase changes, does it modify policies protected by it? Since they know their protectors I'm not sure...

ebiggers commented 7 months ago

Okay, this is expected then. If you use the advanced command fscrypt metadata create policy, for security reasons the resulting policy is owned by the user who ran the command and has mode 0600. If you run the command as root, that means root.

I suppose that if you use fscrypt metadata add-protector-to-policy to add a login protector to a policy, and the user of the login protector can't read the policy, a warning should be printed about the policy not being readable by the user. Currently that doesn't happen, I think.

ardabro commented 7 months ago

Thanks a lot for these explanations! I've used ecryptfs till now, but it is time to switch. Fscrypt looks much better for various reasons, except that I have to deal with reformatting all drives from btrfs to ext4.