I have a machine running Ubuntu with a SSH config file in ~/.ssh/config with the following permissions (default when creating a new file)

-rw-rw-r--  1 dev dev   75 Oct 26 20:13 config

After creating a new user (test) with the same primary group (dev) as the existing user (dev), I am no longer able to git clone when logged in as dev.

dev@vm:~$ git clone ...
Cloning into ...
Bad owner or permissions on /home/dev/.ssh/config
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Googling around seems to suggest that I can fix the ssh problem by running chmod 600 ~/.ssh/config, but why would this even be an issue? How can I fix this systematically, since I assume this would've affected other files too?


  • IME Ubuntu is the only distribution where ls -ald $HOME will show rwxr-xr-x. The problem is detected by ssh, but the root cause is Ubuntu. ("problem" in this case being that this new user you created can get into and change your ssh config etc)
    – user339730
    Nov 2 '20 at 6:10

In the openssh-7.6p1 source code file readconf.c we can see that the permission checking is delegated to a function secure_permissions:

if (flags & SSHCONF_CHECKPERM) {
        struct stat sb;

        if (fstat(fileno(f), &sb) == -1)
                fatal("fstat %s: %s", filename, strerror(errno));
        if (!secure_permissions(&sb, getuid()))
                fatal("Bad owner or permissions on %s", filename);

This function is in misc.c and we can see that it indeed explicitly enforces one member per group if the file is group-writeable:

secure_permissions(struct stat *st, uid_t uid)
        if (!platform_sys_dir_uid(st->st_uid) && st->st_uid != uid)
                return 0;
        if ((st->st_mode & 002) != 0)
                return 0;
        if ((st->st_mode & 020) != 0) {
                /* If the file is group-writable, the group in question must
                 * have exactly one member, namely the file's owner.
                 * (Zero-member groups are typically used by setgid
                 * binaries, and are unlikely to be suitable.)
                struct passwd *pw;
                struct group *gr;
                int members = 0;

                gr = getgrgid(st->st_gid);
                if (!gr)
                        return 0;

                /* Check primary group memberships. */
                while ((pw = getpwent()) != NULL) {
                        if (pw->pw_gid == gr->gr_gid) {
                                if (pw->pw_uid != uid)
                                        return 0;

                pw = getpwuid(st->st_uid);
                if (!pw)
                        return 0;

                /* Check supplementary group memberships. */
                if (gr->gr_mem[0]) {
                        if (strcmp(pw->pw_name, gr->gr_mem[0]) ||
                                return 0;

                if (!members)
                        return 0;
        return 1;
  • 1
    SSH is explicitly made to check the file permissions, and to complain loudly, if another user could modify the configuration because that would be huge gaping security hole. It probably checks the number of users in the group instead of complaining about group-writability as such, since many systems have per-user groups, and umasks allowing write access for the group and false positives there would just annoy people unnecessarily.
    – ilkkachu
    Oct 27 '20 at 12:28
  • 1
    This seems to be Debian-specific - the commit is from Colin Watson, the upstream bug is closed WONTFIX, and I couldn't find this function anywhere in github.com/openssh/openssh-portable
    – muru
    Oct 28 '20 at 5:04

This is related to ssh. Ssh requires the file ~/.ssh/config to be readable only by the user it affects and noone else. File-permission of 664 or 644 is default on most systems (rw-rw-r-- or rw-r--r--). You can control this by setting a umask.

git clone is using ssh to clone the repository, maybe it's using some ssh-stuff on init even when the clone is done from http(s).


  • 4
    Must be WRITABLE only by owner; readable by others is okay for config and pubkey files, including known_hosts and authorized_keys; PRIVATEKEY files must be readable only by owner (even if encrypted, which indepedently should provide confidentiality). I don't know where die.net found a 2013 (!) man page, but see the current maintained versions at man.openbsd.org/ssh.1#FILES and man.openbsd.org/ssh_config.5#FILES Oct 27 '20 at 0:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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