Allowing multiple developers to read/write to website via SFTP or FTP

This article simply exists to serve as a visual reference when I’m explaining permissions to others. If you are looking to apply the concepts in this article on a live site, make sure you create a backup of the permissions and ownerships before proceeding as this article could break a pre-existing site!

This is one of those things where there is more than one way to go about it. The goal here is to allow multiple users the ability to work with the site via FTP/SFTP using basic permissions and groups.

First, create the shared group. In this case, as my domain is going to be, I will call it exampleadmins:

[root@web01 ~]# groupadd exampleadmins

Now add the preexisting users to the group

[root@web01 ~]# usermod -aG exampleadmins user01
[root@web01 ~]# usermod -aG exampleadmins user02

Now change the group ownership recursively on the website directory:

[root@web01 ~]# chgrp -R exampleadmins /var/www/vhosts/

Since we want users in the exampleadmins group to have write access, set the group write permissions on the website directory by:

[root@web01 ~]# chmod -R g+w /var/www/vhosts/

To ensure that any new files or directory inherit the group ownership, use the SetGID bit on the directory recursively:

[root@web01 ~]# find /var/www/vhosts/ -type d -exec chmod g+s "{}" \;

To ensure that files or directories the user creates or uploads are group writable by default, you need to adjust the default umask for the FTP and SFTP server. For vsftpd which is generally the default FTP server, change the default umask from 022 to 002 by:

[root@web01 ~]# vim /etc/vsftpd.conf
local_umask = 002
[root@web01 ~]# service vsftpd restart

When using SFTP, update the sftp subsystem within /etc/ssh/sshd_config to set a umask of 0002 by:

[root@web01 ~]# vim /etc/ssh/sshd_config
Subsystem       sftp    /usr/libexec/openssh/sftp-server -u 0002
# Append to bottom of file:
Match Group exampleadmins
   ForceCommand internal-sftp -u 0002
[root@web01 ~]# service sshd restart

Now whenever you need to add additional users, simply create the user with a membership to exampleadmins

[root@web01 ~]# useradd -s /sbin/nologin -d /var/www/vhosts/ -G exampleadmins user03

And if the user already exists, simply run:

[root@web01 ~]# usermod -aG exampleadmins user03

SSH – Two Factor Authentication

Many people are using Google Authenticator to secure their google apps such as gmail. However what if you wanted to be able to utilize two factor authentication (something you have, something you know) for your SSH logins? What if you want to protect yourself against accidently using weak passwords, which can lead to a successful brute force attack?

On both RedHat and Debian based systems, Google Authenticator’s one time passwords are pretty simple to implement. For the purposes of this guide, I’ll be using CentOS 6 and Ubuntu 12.04.

It should be noted that by using this guide, ALL your users (including root) will be required to use the google authenticator to SSH in unless you have SSH keys already in place. Please check with your administration teams before setting this up to ensure you don’t accidently disable their access, or lock yourself out from SSH!


1. Install the module

# RedHat 6 based systems
rpm -ivh
yum install google-authenticator

# Debian based systems
aptitude install libpam-google-authenticator

2. Now update the /etc/pam.d/sshd file and add the following at the end of the ‘auth’ section:

auth required

3. Then update your /etc/ssh/sshd_config

# Change
ChallengeResponseAuthentication no

# To
ChallengeResponseAuthentication yes

4. Restart sshd

# Redhat:  
service sshd restart

# Ubuntu:  
service ssh restart

5. Now, setup keys for your user


It will ask you to update your ~/.google_authenticator file, answer yes to this question, and whatever you would like to use for the next three. Once complete, the following will be present to you:

    New Secret Key
    Verification Code
    Emergency Scratch Codes

You will use the new secret key for adding the account to your phone’s google authenticator app. The emergency scratch codes should be copied down and stored somewhere secure. They can be used if you ever lose your iphone, or otherwise need to get into your account without your phone’s google authenticator app.

Now when you log into your server using your user account, it will prompt you for your google auth token, followed by your normal password for the server. Any accounts that don’t have the this setup will not be allowed to log in.

Final thoughts

Remember, two factor authentication is only one part of a defense in depth strategy. No security management system is perfect, but each layer you add will help increase your solutions security footprint.

RHCSA Study Guide – Objective 5 : Users

Everything below are my raw notes that I took while attending an unofficial RHCSA training session.  I am posting them here in hopes they will assist others who may be preparing to take this exam.  

My notes are my own interpretation of the lectures, and are certainly not a replacement to classroom training either through your company, or by taking the official RHCSA classes offered through Red Hat.  If you are new to the Red Hat world, I strongly suggest looking into their training courses over at Red Hat.

Users and Groups

EXAM NOTE: On the test, I will likely have to link this machine to a ldap or nis server.

Users and Groups define access to the OS through the file permission scheme. Root is the super user (uid 0). All users are associated with at least one group. Secondary group memberships can exist too.

User info is stored in:


/etc/passwd has 7 fields

1.  username
2.  Where the pw used to be set, (but exists in /etc/shadow, so its just a place holder)
3.  Numberical identify for the account (UID)
4.  Numerical idenitfer for the primary group (GID)
5.  Comments field (aka gecos field). 
6.  Home directory where your homedir exists
7.  Your shell or program that executes when you log in.

/etc/shadow has 2 important fields

- login:encrypted_password: (The rest are password aging fields).
- aging fields track dates for passwd resets locks, etc


- group name, pw, gid,membergroups.  
- Group passwords allow temp management to a group are rarely used and not setup by default.

Management tools:

1. useradd – add user. Most common option is -g to specify primary group, and -G to add secondary groups. Example:

[root@web01 ~]# useradd -g clowns -G trouble,simpson bart

2. usermod – Modify a users settings. It takes pretty much all the options as useradd. Though, when modifying group behaviors, when you try to add him to a secondary group, just run:

[root@web01 ~]# usermod -a -G detension bart

3. userdel – Remove user from system. If you give it a -r, it’ll also remove his homedir and spool directories. Example:

userdel -r moe

4. groupadd – Add new group
5. groupmod – Mainly used to rename a group ex. groupmod -n mktg mkg
6. groupdel – Remove a group. Ex. groupdel microsoft
7. passwd – change pw
a. root can change all
b. can diasble accounts ex. passwd -l mary
c. Setup passwd aging
d. Time passwd resets
e. Account disabling (or use chage)

Passord aging

You can set max / min lifetimes for a user’s password.

[root@web01 ~]# passwd -x days user

When a users pw has expired, you can set the nuber of days it can remain expired before disabling the account completely:

[root@web01 ~]# passwd -i days user

User environment files

Used files or defaults when creating accounts

1.  /etc/skel : default template for newly added users homedir
2.  /etc/profile : sets env variabled used by all users
3.  /etc/profile.d : contains scripts specific to certain rpms
4.  /etc/bashrc : contains global aliases and system settings
5.  ~/.bashrc : contains users aliases and functions
6.  ~/.bash_profile : contains user env settings, and can be set to automatically start programs at login.


EXAM NOTE: ALL this stuff is on the test.

1.  Create a new group 'dev'.  Create a new user 'alice' as a member of the 'dev' group, with a description of 'Alice from Dev' and a default shell of '/bin/csh'.  Use the password command to set a password for alice, then log in as alice and verify her access.

[root@web01 ~]# groupadd dev
[root@web01 ~]# useradd -G dev -c "Alice from Dev" -s /bin/csh alice
[root@web01 ~]# passwd alice

2.  Set a maximun pw lifetime of 4 weeks for the alice account.  Look at the password, shadow, and group files

[root@web01 ~]# passwd -x 30 alice

3.  Configure the users simon, linus, richard.  Set all their passwords to 'linux'
[root@web01 ~]# groupadd ru
[root@web01 ~]# useradd -G ru simon
[root@web01 ~]# useradd -G ru linus
[root@web01 ~]# useradd -G ru richard
[root@web01 ~]# passwd simon
[root@web01 ~]# passwd linux
[root@web01 ~]# passwd richard

4.  Make these users part of the ru group
See #3

5.  Configure the directory /home/linux so that each user from the ru group can read, create, and modify files:
[root@web01 ~]# mkdir /home/linux
[root@web01 ~]# chown -R root:ru /home/linux
[root@web01 ~]# chmod 775 /home/linux
[root@web01 ~]# chmod g+s /home/linux # This means that any files created in here will be writable by group ru regardless of ownership.

6.  Configure the directory /home/linux/work so that each user can create and read files, but only the files's owner can delete.
[root@web01 ~]# mkdir /home/linux/work
[root@web01 ~]# chown root:ru /home/linux/work
[root@web01 ~]# chmod 775 /home/linux/work
[root@web01 ~]# chmod -t /home/linux/work

7.  Use ACL's to allow alice, not in 'ru', access to the work folder.
[root@web01 ~]# setfacl -R -m u:alice:rwx /home/linux/work
[root@web01 ~]# setfacl -m default:u:alice:rwx /home/linux/work # As new objects are created in here, they will inherit the acl's.


NIS and LDAP Servers can be configured to centrally manage system and account info.

NIS – This is suppose to be a very basic management system.

[root@web01 ~]# yum install rpcbind ypbind
[root@web01 ~]# system-config-authentication  # <-- GUI tool for setting this up.  Does everything for you.
[root@web01 ~]# setup -> authentication configuration

It’ll modify:


LDAP – Widely used, flexible db for storing mac, unix, windows, acl’s, and a whole lot more.

[root@web01 ~]# yum install nss-pam-ldapd
[root@web01 ~]# system-config-authentication

It’ll modify:


EXAM NOTE: You just need to know how to configure the clients. Setting up the servers isn’t required for rhcsa or rhce.

[root@web01 ~]# vim /etc/auto.nis
* server1:/nis/&

[root@web01 ~]# man 5 autofs

Side note:

All the kernel documentation that exists is available via:

[root@web01 ~]# yum install kernel-doc
[root@web01 ~]# cd /usr/share/docs/kernel-docs/blah

Using PAM to enforce access based on time

Sometimes there is a need to restrict user access based on time. This could be access to one particular service, or all PAM enabled services. A common example is to only allow access for the user ‘bob’ monday through friday between 9:00AM – 6:00PM. This can be enforced by utilizing the pam_time module.

The pam_time module is an account module type. No arguments are passed directly to the module, but instead all configuration takes place within /etc/security/time.conf.

The time.conf operates based on rules, and each rule uses the following syntax:


Example Rules
Restrict SSHD access for bob to weekdays between 9:00AM – 7:00PM


Restrict ALL access for bob to weekdays between 9:00AM – 5:00PM


Restrict ALL access for ALL users except root to weekdays between 9:00AM – 5:00PM


Restrict SSH access for ALL users except bob and jane to weekdays between 9:00AM – 5:00PM


To only allow bob to access SSH on Tuesdays between 3:23PM and 4:24PM:


Below is all the available abbreviates for the days of the week:

Mo : Monday Fr : Friday Wd : Sa/Su
Tu : Tuesday Sa : Saturday wk : Mo/Tu/We/Th/Fr
We : Wenesday Su : Sunday
Th : Thursday Al : All Days

Installation And Configuration
In our example, I am going be setting this up on a CentOS 5.x server. For the restricted user, the following variables will be used:

username: bob
allowed access times: 9:00AM - 6:00PM
restricted services: SSHD

First, add the user and time restriction to /etc/security/time.conf:


Now, update the pam module for login and sshd. You are including ‘account required‘. But I’ll post entire file for reference

cat /etc/pam.d/sshd
auth required
auth include password-auth
account required
account required
account include password-auth
password include password-auth
# close should be the first session rule
session required close
session required
# open should only be followed by sessions to be executed in the user context
session required open env_params
session optional force revoke
session include password-auth
cat /etc/pam.d/system-auth
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth required
auth sufficient nullok try_first_pass
auth requisite uid >= 500 quiet
auth required
account required
account required
account sufficient
account sufficient uid < 500 quiet
account required
password requisite try_first_pass retry=3 type=
password sufficient md5 shadow nullok try_first_pass use_authtok
password required
session optional revoke
session required
session [success=1 default=ignore] service in crond quiet use_uid
session required

And finally, restart SSH

service sshd restart