User authentication at Savannah
User account creation
- Anyone can register a Savannah account using the web interface: https://savannah.gnu.org/account/register.php
- These accounts are used across all Savannah systems.
- Users can upload ssh public keys using the web interface at: https://savannah.gnu.org/my/admin/editsshkeys.php
- SSH public keys are stored in the database on
internal0.savannah.gnu.org
(see SavannahServices).
User information can be viewed by anyone on Savannah website.
Example for user agn
: https://sv.gnu.org/users/agn/
Database access
In the database, currently internal0.savannah.gnu.org
but
accessible from a set of hosts, the following SQL commands
can be used to examine accounts:
$ echo "select
user_id, user_name, email, realname,
uidNumber, authorized_keys
from user
where user_name = 'agn'" \
| mysql savane
+---------+-----------+----------+--------------+-----------+-----------------+
| user_id | user_name | email | realname | uidNumber | authorized_keys |
+---------+-----------+----------+--------------+-----------+-----------------+
| 94790 | agn | [email] | Assaf Gordon | 131035 | ssh-rsa AAAAB3Nz|
+---------+-----------+----------+--------------+-----------+-----------------+
The authorized_keys
field contains all user's SSH public keys,
concatenated with a ###
delimiter, as a one-line string.
Users upload their SSH keys, and they are stored in the database.
Some users have uploaded malformed and invalid GPG key
information. Therefore some of these records are invalid due to
having invalid information uploaded.
Activating accounts
This is done via the web siteadmin interface: Main page -> Browse Users List -> find user -> [Activate] in the Actions column.
Groups and accounts
In Savannah systems, there is a Unix user for each Savannah registered account that is a member of at least one group:
download0:~# getent passwd agn
agn:x:131035:1003:Assaf Gordon:/etc/savane/user-home-dir:/etc/savane/user-shell
and a Unix group for each Savannah registered group:
vcs0:~# getent group datamash
datamash:x:77800:agn
Access control is based on Unix group membership.
Example:
The gawk
(GNU Awk) group (http://sv.gnu.org/p/gawk) has six
members as of Nov. 2014
(http://sv.gnu.org/project/memberlist.php?group=gawk).
The git repository on vcs.sv.gnu.org
belongs in the gawk
group:
vcs0:~# ls -ld /srv/git/gawk.git/
drwxrwsr-x 8 root gawk 4096 Nov 4 01:23 /srv/git/gawk.git/
The members of the gawk
group are allowed to push code updates to the gawk
repository:
vcs0:~# getent group gawk
gawk:x:6731:ajschorr,arnold,eliz,jkahrs,scldad,wb8tyw
Authentication mechanisms
For VCS repositories (git/hg/bzr/svn/cvs on vcs.sv.gnu.org
) and
download area (on dl.sv.gnu.org
), users are authenticated using SSH
access and their public keys. See SavannahServices for details about the
available services on these servers.
Savannah users who are not members of any group (i.e., do not have
write access to any repository) do not have SSH login access on vcs
even if they have set up their SSH keys. getent passwd USER
will
return empty results for such users, even if they are valid users in the
database (i.e., they exist in the users
mysql table).
Technically, this is due to the libnss-mysql (see below) script doing an
SQL JOIN on the user
and user_group
tables, and requiring having at
least one record in the user_group
table. Maybe someday this will be
changed.
These servers use the database in two ways:
- Unix user management, using nsswitch and libnss-mysql.
- SSH key authentication, using the custom
AuthorizedKeysCommand
option.
nsswitch
The file vcs0:/etc/nsswitch.conf
contains the following configuration:
...
passwd: compat mysql
group: compat mysql
shadow: compat mysql
...
Bob Proulx explains:
That is how libc is configured. 'compat' means /etc/passwd in the normal compatible way. 'mysql' means if not found in the first compat section then look it up in mysql. That is what allows libc to find users in the mysql database.
vcs0:~# getent passwd agn
agn:x:131035:1003:Assaf Gordon:/var/local/git-shell-home:/usr/local/bin/shellcmdfw
The SQL statements to extract information from the database on
internal0
are defined in vcs0:/etc/libnss-mysql.cfg
.
The download0 host is configured to use libnss-extrausers instead of libnss-mysql.cfg; its /etc/nsswitch.conf contains the following:
...
passwd: files extrausers
group: files extrausers
shadow: files
...
download0:/var/lib/extrausers/passwd
and download0:/var/lib/extrausers/group
are linked from /net/vcs/var.lib.savane/; those files are updated on frontend
whenever the set of any group members is modified.
download:~# getent passwd agn
agn:x:131035:1003:Assaf Gordon:/etc/savane/user-home-dir:/etc/savane/user-shell
download0:/etc/savane/user-home-dir
and download0:/etc/savane/user-home-dir
link to /srv and /opt/savane/bin/sv_membersh, respectively.
uidNumber
Savannah users have two IDs in the database: user.user_id
and
user.uidNumber
. user_id
is used in the PHP frontend alone
(it is the primary key for the user table). uidNumber
is the
user's unix account user ID (used by getent
above).
When a new user is registerd on Savannah, the user_id
will be
unique, but the uidNumber
will be NULL.
A cron job (mgt1:/etc/cron.d/savannah
) calls a script (sv_assign_uid_gid)
which scans the new users in the database, and creates unix user IDs if needed
(if users are not part of any group, they won't need SSH access and thus won't
need user ID).
Search for sv_assign_uid_gid
in SavannahInternals to see how it is called.
SSH authentication
The file /etc/ssh/sshd_config
on download0:
and vcs0:
servers have the line:
...
AuthorizedKeysCommand /opt/savane/bin/sv_get_authorized_keys
...
When users log in to Savannah servers using SSH, they specify the account:
git clone agn@git.sv.gnu.org:/srv/git/datamash.git
The user is therefore known, and OpenSSH needs to find user's public keys.
The sv_get_authorized_keys
Perl script simply queries
the SSH public keys of the user (splitting them by ###
delimiter):
...
my ($authorized_keys) = $dbd->selectrow_array(q[
SELECT authorized_keys
FROM user
WHERE user_name = ?], undef, $user);
print join("\n", split('###', $authorized_keys));
...
Manually invoking sv_get_authorized_keys
looks like:
vcs0:~# /opt/savane/bin/sv_get_authorized_keys agn
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvs [...]
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ [...]
mgt and root access
mgt1.savannah.gnu.org
is the management server (see SavannahArchitecture for
more details).
root access to mgt1
(and from there to the other Savannah servers) is
controlled by mgt1:/root/.ssh/authorized_keys
. This file is updated
manually by existing Savannah administrators, adding ssh public keys
of authorized Savannah hackers.
ssh access to mgt1
is only possible from fencepost
(and other
internal FSF machines to which no one outside the FSF has access).
ssh access to vcs0 and download0 is open to all as required by their
respective functions.
fencepost
fencepost.gnu.org
is the general-purpose server for GNU hackers (for more
information: https://www.gnu.org/software/README.accounts.html).
It is managed by FSF sysadmin, and not managed by Savannah people in any way whatsoever.
GNU webpage repository access for www members
Members of the www group (= GNU webmasters) have write access to the webpage repository for all gnu (not nongnu) groups. This is accomplished with ACLs. See ChangeLog entries by Beuc for 2006-06-28 and 2006-05-10, recorded in http://lists.gnu.org/archive/html/savannah-hackers-public/2016-05/msg00031.html. The key command is:
setfacl -m group:www:rw- FILES
setfacl -m default:group:www:rwx -m group:www:rwx DIRS
To set all of them I think this is needed. Testing it now.
setfacl -m group:www:rw- group/CVSROOT/history
find group/group -type d -exec setfacl -m default:group:www:rwx -m group:www:rwx {} +
find . -name CVSROOT -prune -o -type f -exec setfacl -m group:www:rw- {} +
The Cvs.pm
Savane module installs this access for new gnu groups.