When multiple users in the same group need to collaborate on shared files while maintaining security boundaries, Linux permission systems become crucial. The ideal setup requires:
Files: rw-rw-r-- (664)
Directories: rwxrwx--x (771)
This ensures group members can modify files while restricting world access appropriately. Yet achieving consistency across different file operations proves challenging.
The umask value subtracts permissions from the default creation mode. Key concepts:
Default file creation: 666 - umask
Default directory creation: 777 - umask
For our target permissions (664/771), the required umask would be:
Files: 666 - 664 = 0022
Directories: 777 - 771 = 0006
For SSH and local logins, modify /etc/pam.d/common-session
:
session optional pam_umask.so umask=0022
For SSH specifically, edit /etc/pam.d/sshd
:
session optional pam_umask.so umask=0022
When using SSHFS, the umask calculation differs because FUSE starts from 777 permissions. Use:
sshfs -o umask=0113 -o fmask=0113 -o dmask=0026 user@host:/path /mnt
Breakdown:
- fmask=0113: 777 - 664 = 113
- dmask=0026: 777 - 751 = 026
For GNOME/Nautilus operations, create /etc/profile.d/nautilus-umask.sh
:
if [ "$XDG_CURRENT_DESKTOP" = "GNOME" ]; then
umask 0022
fi
For SCP transfers, the server-side OpenSSH configuration requires modification:
# In /etc/ssh/sshd_config
Subsystem sftp /usr/lib/openssh/sftp-server -u 0022
Create a custom pam_umask script at /etc/pam.d/custom-umask
:
# Set different umask for files vs directories
if [ -d "$1" ]; then
umask 0006 # Directories
else
umask 0022 # Files
fi
Create a test script to verify permissions across operations:
#!/bin/bash
echo "Testing permission consistency:"
touch testfile
mkdir testdir
scp testfile localhost:~/scpfile &> /dev/null
printf "%-20s %s\n" "Operation" "Permissions"
printf "%-20s %s\n" "Local file:" $(stat -c %a testfile)
printf "%-20s %s\n" "Local directory:" $(stat -c %a testdir)
printf "%-20s %s\n" "SCP transferred file:" $(stat -c %a ~/scpfile)
- Verify PAM module order in configuration files
- Check for conflicting umask settings in shell profiles
- Confirm SELinux/AppArmor isn't interfering
- Test with different user accounts to verify group permissions
- Monitor audit logs for permission-related events
When multiple developers collaborate on a shared Linux server, permission management becomes critical. The ideal scenario requires:
# Desired permissions structure
Files: -rw-rw-r-- (664)
Directories: drwxrwx--x (771)
The fundamental issue arises from different tools interpreting umask differently:
# Demonstrating permission discrepancies
$ touch ssh_created_file # Shows 664 (correct)
$ scp local_file remote: # Results in 711 (wrong)
$ sftp> put local_file # Results in 777 (wrong)
$ nautilus copy # Creates 600 (wrong)
For system-wide umask enforcement, modify the PAM configuration:
# /etc/pam.d/common-session addition
session optional pam_umask.so umask=0002
Different access methods require different approaches:
For SSHFS Mounts
# Correct sshfs mount command
sshfs -o umask=0113,uid=$(id -u),gid=$(id -g) \
user@server:/path /mnt/point
For SCP Transfers
# Force permissions through .bashrc
if [ -n "$SSH_CONNECTION" ]; then
umask 0002
fi
Linux doesn't natively support different umasks, but we can create a workaround:
# In /etc/bashrc or /etc/profile
umask 0002
alias mkdir='mkdir -m 771'
For complex permission scenarios, consider ACLs:
# Set default ACLs for the shared directory
setfacl -d -m g:uploaders:rwX,d:g:uploaders:rwX /shared
Create a test script to verify behavior:
#!/bin/bash
# permission_test.sh
echo "Testing creation methods:"
echo -n "Direct touch: "; touch direct; ls -l direct | awk '{print $1}'; rm direct
echo -n "SCP transfer: "; echo test > local; scp local localhost:remote 2>/dev/null; ls -l remote | awk '{print $1}'; rm remote local
- Set system-wide umask in /etc/pam.d/common-session
- Configure sshd to preserve group permissions
- Implement directory-specific creation commands
- Consider ACLs for complex sharing requirements