umask and login.defs, the secure way
You set UMASK 027 in /etc/login.defs, logged in again, typed umask, and it still said 0022. You're not crazy, you heard right: on many systems that line is only read by a module nobody enabled.
The short answer
Set UMASK 027 and HOME_MODE 0700 in /etc/login.defs so new home directories are private. Make sure pam_umask is in the PAM session stack, or the login umask never changes. Set UMask=0027 in each systemd service, because services do not log in. Fix existing home directories by hand.
On this page
What goes wrong
The umask decides the permissions of every new file and directory. The usual
default, 022, means "everyone may read". On a shared host that makes every
new file readable by every other user and every other service account: config
exports, database dumps, notes with passwords in them.
Home directories have the same problem. On Debian and Ubuntu, useradd -m
creates /home/<user> with mode 755, so any local account can list and read
another user's files unless each user fixes it.
The trap is where the setting lives. /etc/login.defs has a UMASK line, and
it looks like the obvious switch. For logins, it is only applied by
pam_umask, and a Debian 12 container image does not load that module at all.
Services started by systemd ignore both and use their own default.
What the docs say
The file mode creation mask is initialized to this value. If not specified, the mask will be initialized to 022. [...] It is also used by pam_umask as the default umask value.
Source: login.defs(5), UMASK
The mode for new home directories. If not specified, the UMASK is used to create the mode.
Source: login.defs(5), HOME_MODE
Controls the file mode creation mask. Takes an access mode in octal notation. See umask(2) for details. Defaults to 0022 for system units.
Source: systemd.exec(5), UMask=
login.defs(5) says the mask "is initialized" to UMASK, but it does not
say which program does that on your distribution. Check your PAM files before
you trust it.
The secure configuration
# /etc/login.defs (edit the existing lines)
# New files: owner read/write, group read, others nothing. New dirs: 750.
UMASK 027
# New home directories: owner only.
HOME_MODE 0700Make sure logins apply it. On Debian and Ubuntu:
# Is pam_umask in the session stack? 0 means no.
grep -c pam_umask /etc/pam.d/common-session
# If it is missing, add it (reads UMASK from /etc/login.defs):
echo "session optional pam_umask.so" >> /etc/pam.d/common-sessionOn Rocky Linux 9 the stock /etc/pam.d/postlogin already has
session optional pam_umask.so silent and login.defs already sets
HOME_MODE 0700, so changing UMASK is enough there. Check with
grep -rn pam_umask /etc/pam.d/, and look for umask lines in
/etc/profile and /etc/bashrc that could override it.
Services do not log in, so give each one its own mask:
# /etc/systemd/system/app.service.d/umask.conf
[Service]
# Files the service creates: 640, directories: 750.
UMask=0027Existing home directories keep their old mode. Fix them once:
for d in /home/*/; do chmod 0700 "$d"; doneProve it
The stock Debian 12 image: UMASK 022, HOME_MODE commented out, and no
pam_umask in the session stack. A new user gets a readable home and
readable files:
grep -E "^#?(UMASK|HOME_MODE)" /etc/login.defs
grep -c pam_umask /etc/pam.d/common-session
useradd -m -s /bin/bash alice
stat -c "%A %U %n" /home/alice
su - alice -c "umask; touch notes.txt; mkdir reports; ls -ld notes.txt reports"UMASK 022
#HOME_MODE 0700
0
drwxr-xr-x alice /home/alice
0022
-rw-r--r-- 1 alice alice 0 Sep 24 20:36 notes.txt
drwxr-xr-x 2 alice alice 4096 Sep 24 20:36 reportsChange only login.defs. The new home directory is private, but the login
umask is still 0022:
useradd -m -s /bin/bash bob
stat -c "%A %U %n" /home/bob
su - bob -c umaskdrwx------ bob /home/bob
0022Add pam_umask and log in again:
echo "session optional pam_umask.so" >> /etc/pam.d/common-session
su - bob -c "umask; touch notes.txt; mkdir reports; ls -ld notes.txt reports"0027
-rw-r----- 1 bob bob 0 Sep 24 20:36 notes.txt
drwxr-x--- 2 bob bob 4096 Sep 24 20:36 reportsThe difference for other users, and the old home that did not change:
su - bob -c "head -c0 /home/alice/notes.txt && echo bob can read /home/alice/notes.txt"
su - alice -c "ls /home/bob"
stat -c "%a %n" /home/alice
chmod 0700 /home/alice
stat -c "%a %n" /home/alicebob can read /home/alice/notes.txt
ls: cannot open directory '/home/bob': Permission denied
755 /home/alice
700 /home/aliceThe test script is secure-tests/umask-login-defs/run.sh.
Mistakes people make
Trusting login.defs on its own
UMASK in login.defs changes the login umask only if pam_umask runs.
Always check with umask in a fresh login, not by reading the file.
Forgetting services
A web app or backup job started by systemd uses UMask= from its unit, which
defaults to 0022. The files it writes, often the sensitive ones, stay
world-readable until you set it.
Going straight to 077 everywhere
077 also removes group read, which breaks setups where a group is meant to
share files (a deploy group reading app config, for example). 027 keeps
the group and removes everyone else. Use 077 for single-user hosts.
Expecting old files to change
A umask applies when a file is created. Files and home directories that
already exist keep their mode. Find them with
find /home -maxdepth 1 -type d -perm -o+r.
Checklist
/etc/login.defshasUMASK 027andHOME_MODE 0700.pam_umaskis in the PAM session stack, or the shell startup files setumask 027.- A fresh login prints
0027forumask. - Each custom systemd service sets
UMask=0027or stricter. - Every existing home directory is mode
0700or0750. - A test file created by a normal user is not readable by another user.
The umask is the quietest security setting on the host. Set it once, prove it once, and every file created afterward is private by default.
FND
Learn it on a live range
Linux 1: the command line to a working, secure host, in Foundation: a real host in your browser, and every objective checked on the machine.
Start freeThe Secure Way
More on linux hosts
SSH, sudo, firewalls, mount options, updates and the host basics every engineer should get right.
All linux hosts guides