Difference between revisions of "User Management (Buster)"

From Hexwiki
Jump to navigation Jump to search
 
(7 intermediate revisions by the same user not shown)
Line 53: Line 53:
  
 
  mkdir /etc/skel/.ssh
 
  mkdir /etc/skel/.ssh
  touch /etc/skel/.ssh/authorized_keys /etc/skel/.toprc /etc/skel/.viminfo
+
mkdir /etc/skel/bin
  chmod 640 /etc/skel/.bash_logout /etc/skel/.bashrc /etc/skel/.profile /etc/skel/.toprc /etc/skel/.ssh/authorized_keys /etc/skel/.viminfo
+
  touch /etc/skel/.ssh/authorized_keys /etc/skel/.toprc /etc/skel/.viminfo /etc/skel/.bash_history
  chmod 750 /etc/skel/.ssh/ /etc/skel/
+
  chmod 640 /etc/skel/.bash_logout /etc/skel/.bashrc /etc/skel/.profile /etc/skel/.toprc /etc/skel/.ssh/authorized_keys /etc/skel/.viminfo /etc/skel/.bash_history
 +
  chmod 750 /etc/skel/.ssh/ /etc/skel/ /etc/skel/bin
  
 
I also add my own public key to authorized_keys here.
 
I also add my own public key to authorized_keys here.
Line 138: Line 139:
  
 
  cp -R /etc/skel /etc/webskel
 
  cp -R /etc/skel /etc/webskel
  mkdir /etc/webskel/logs
+
  mkdir /etc/webskel/pool
 
  mkdir /etc/webskel/docs
 
  mkdir /etc/webskel/docs
 
  mkdir /etc/webskel/priv
 
  mkdir /etc/webskel/priv
  chmod 750 /etc/webskel/logs /etc/webskel/docs /etc/webskel/priv
+
mkdir /etc/webskel/sock
 +
  chmod 750 /etc/webskel/pool /etc/webskel/docs /etc/webskel/priv /etc/webskel/sock
  
 
* /etc/webskel/.ssh/authorized_keys
 
* /etc/webskel/.ssh/authorized_keys
Line 151: Line 153:
 
** DSHELL=/usr/sbin/nologin
 
** DSHELL=/usr/sbin/nologin
 
** SKEL=/etc/webskel
 
** SKEL=/etc/webskel
 
  
 
== User adding scripts ==
 
== User adding scripts ==
Line 173: Line 174:
 
  #!/bin/sh
 
  #!/bin/sh
 
  # This still doesn't do everything it should. Need to flesh it out more.
 
  # This still doesn't do everything it should. Need to flesh it out more.
  if [ $1 ] ; then
+
  if [ $1 ] && [ $2 ] && [ $3 ] ; then
  /usr/sbin/adduser --shell /usr/sbin/nologin --disabled-password --gecos "" --conf /etc/webuser.conf $1
+
  export KEYFILE="/etc/certs/$2.key"
  /usr/sbin/usermod -a -G website $1
+
  export CSRFILE="/etc/certs/$2.csr"
  /bin/sed "s/USERNAME/$1/g" /root/fpmnginx.conf > /etc/nginx/sites/$1.conf
+
  /usr/bin/openssl genrsa -out $KEYFILE 4096
  /bin/sed "s/USERNAME/$1/" /root/fpmpool.conf > /etc/php5/fpm/pool.d/$1.conf
+
  /bin/chmod 0600 $KEYFILE
  /bin/chmod 0751 /home/$1
+
  /bin/sed -e "s/DOMAIN/$2/g" /root/csr.cnf > /root/csr$2.cnf
  /bin/chown root /home/$1
+
  /usr/bin/openssl req -new -config /root/csr$2.cnf -key $KEYFILE -out $CSRFILE
  /bin/chown root /home/$1/.ssh
+
  /usr/sbin/adduser --shell /usr/sbin/nologin --disabled-password --gecos "" --conf /etc/webuser.conf $1
  /bin/chown root /home/$1/.ssh/authorized_keys
+
  /usr/sbin/usermod -a -G website $1
  /bin/chgrp www-data /home/$1/docs
+
  /usr/bin/mkdir /var/log/$2
  /usr/bin/systemctl restart php-fpm
+
  /bin/chmod 0750 /var/log/$2
 +
  /bin/chown $1:adm /var/log/$2
 +
  /usr/bin/ln -sv /var/log/$2 /home/$1/logs
 +
  /bin/sed "s/USERNAME/$1/g; s/DOMAIN/$2/g; s/IPADDRESS/$3/g" /root/fpmnginx.conf > /etc/nginx/sites/$1.conf
 +
  /bin/sed "s/USERNAME/$1/" /root/php-fpm.7.4.conf > /home/$1/pool/$2.conf
 +
  /bin/sed "s/USERNAME/$1/" /root/php-logrotate.template > /etc/logrotate.d/php-$1
 +
  /bin/sed "s/USERNAME/$1/g; s/DOMAIN/$2/g" /root/php7.4-fpm.service.template > /etc/systemd/system/multi-user.target.wants/fpm-$2.service
 +
  /bin/chmod 0751 /home/$1
 +
  /bin/chown root /home/$1
 +
  /bin/chown root /home/$1/.ssh
 +
  /bin/chown root /home/$1/.ssh/authorized_keys
 +
  /bin/chgrp www-data /home/$1/docs
 +
  /bin/chgrp www-data /home/$1/sock
 +
  /usr/bin/systemctl start fpm-$2.service
 
  else
 
  else
  echo "Usage: webadd.sh username"
+
  echo "Usage: webadd.sh username domain ipaddress"
 
  fi
 
  fi
  
 
This makes use of the templates we make in other parts of the guide, applying them accordingly.
 
This makes use of the templates we make in other parts of the guide, applying them accordingly.
  
While the nginx config is connected to fpm properly, you still need to assign an IP address and call it.
+
A few go here:
 +
 
 +
=== /root/php-logrotate.template ===
 +
 
 +
/var/log/USERNAME/*.log {
 +
        rotate 26
 +
        weekly
 +
        missingok
 +
        notifempty
 +
        create 0640 USERNAME adm
 +
        compress
 +
        delaycompress
 +
        postrotate
 +
                kill -USR1 $(cat /home/USERNAME/pool/fpm-USERNAME.pid) > /dev/null
 +
        endscript
 +
}
 +
 
 +
=== /root/csr.cnf ===
 +
 
 +
# Template file for automagic csr generation.
 +
# Import domain name
 +
FQDN = DOMAIN
 +
 
 +
# the name of your organization
 +
ORGNAME = myorgname
 +
 
 +
# Mainly for www. but can add others, of course.
 +
ALTNAMES = DNS:$FQDN, DNS:www.$FQDN # , DNS:bar.$FQDN , DNS:www.foo.$FQDN
 +
 
 +
[ req ]
 +
default_bits = 4096
 +
default_md = sha256
 +
prompt = no
 +
encrypt_key = no
 +
distinguished_name = dn
 +
req_extensions = req_ext
 +
 
 +
[ dn ]
 +
C = US
 +
O = $ORGNAME
 +
CN = $FQDN
 +
 
 +
[ req_ext ]
 +
subjectAltName = $ALTNAMES
 +
 
  
 
{{Bottom Buster}}
 
{{Bottom Buster}}

Latest revision as of 03:44, 24 January 2021

At best, there's me, and one or two people I'm training, who actually have shell access.

So I make my user settings pretty global.

Users and Groups

Some of this stuff is discussed in various relevant sections as well.

addgroup --gid 70 wheel
addgroup --gid 72 hugepager
addgroup --gid 74 website
addgroup --gid 900 vmail
grpck -s
useradd -d /var/vmail -s /usr/sbin/nologin -g 900 -r -u 900 vmail
usermod -a -G adm,cdrom,audio,src,staff,games,users,wheel adminusernamehere
usermod -a -G wheel root

Adding wheel to root is necessary for later security measures.

/etc/bash.bashrc

I add:

# Enable completion
shopt -s globstar
shopt -s histappend
HISTCONTROL=ignoreboth
HISTFILESIZE=65536
HISTSIZE=256
# There is a point at which either just typing it
# again or looking through the file is more productive...

Bash completion is provided through /etc/profile.d/ so no need to uncomment.

/etc/profile.d/ls.sh

# Colors and aliasing
# Prefer to set this up as an 'include' instead. Easier to make
# alias changes that I may be using across a large number of accounts.
# Check for interactive bash
[ -z "$BASH_VERSION" -o -z "$PS1" ] && return
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto -A'
    alias l='ls --color=auto -la'
else
    alias ls='ls -A'
    alias l='ls -la'
fi

Default /etc/skel

mkdir /etc/skel/.ssh
mkdir /etc/skel/bin
touch /etc/skel/.ssh/authorized_keys /etc/skel/.toprc /etc/skel/.viminfo /etc/skel/.bash_history
chmod 640 /etc/skel/.bash_logout /etc/skel/.bashrc /etc/skel/.profile /etc/skel/.toprc /etc/skel/.ssh/authorized_keys /etc/skel/.viminfo /etc/skel/.bash_history
chmod 750 /etc/skel/.ssh/ /etc/skel/ /etc/skel/bin

I also add my own public key to authorized_keys here.

/etc/skel/.toprc

RCfile for "top with windows"           # shameless braggin'
Id:a, Mode_altscr=0, Mode_irixps=1, Delay_time=0.500, Curwin=2
Def     fieldscur=ABEGHIOPSQTNWKMcdfJLrUVYZX
        winflags=64808, sortindx=0, maxtasks=0
        summclr=1, msgsclr=1, headclr=3, taskclr=1
Job     fieldscur=ABcefgjlrstuvyzMKNHIWOPQDX
        winflags=64825, sortindx=0, maxtasks=0
        summclr=6, msgsclr=6, headclr=7, taskclr=1
Mem     fieldscur=ABGCNOPQRSTUVdefJlMyzWHIKX
        winflags=64808, sortindx=2, maxtasks=0
        summclr=2, msgsclr=1, headclr=6, taskclr=1
Usr     fieldscur=ABDECGfhijlopqrstuvyzMKNWX
        winflags=62777, sortindx=4, maxtasks=0
        summclr=3, msgsclr=3, headclr=2, taskclr=3

I am addicted to my personal top settings.


/etc/skel/.bashrc

After removing unnecessary stuff it looks more like:

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac
# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi
# Get your fortune cookie!
# Place here so user can nuke/edit as desired.
# Probably should fix cowsay to handle line breaks better.
if [ -f /usr/games/fortune ]; then
  if [ -f /usr/games/cowsay ]; then
    /usr/games/fortune -a | /usr/games/cowsay -W 75 -p
  else
    /usr/games/fortune -a
  fi
fi

/root/.bashrc

While I copy other skeleton files to root/admin users, a separate .bashrc file is nice even if some of the reason for it is legacy. The talking cow does get a bit annoying bouncing in and out of root all the time.

# ~/.bashrc: executed by bash(1) for non-login shells.
#When restarting mysql, the memlock value gets taken from root's limits, so if we
#are more restrictive, hugepage allocation will fail.
ulimit -l 134217728
ulimit -n 1048576
# If not running interactively, don't do anything further
case $- in
    *i*) ;;
      *) return;;
esac
# Alias definitions.
# I like using nologin for most users, but this can make maintenance difficult, so...
alias sub="su -s /bin/bash"
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

/etc/webskel

A web skeleton file to help simplify site deployment.

cp -R /etc/skel /etc/webskel
mkdir /etc/webskel/pool
mkdir /etc/webskel/docs
mkdir /etc/webskel/priv
mkdir /etc/webskel/sock
chmod 750 /etc/webskel/pool /etc/webskel/docs /etc/webskel/priv /etc/webskel/sock
  • /etc/webskel/.ssh/authorized_keys
    • add no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding before ssh-rsa for each key, as well as when you add user keys.
cp /etc/adduser.conf /etc/webuser.conf
  • /etc/webuser.conf:
    • DSHELL=/usr/sbin/nologin
    • SKEL=/etc/webskel

User adding scripts

Because it's all about typing fewer characters.

/root/secadd.sh

#!/bin/sh
# This is for adding other administrative users, special
# accounts (e.g. for minecraft or git) and so on.
if [ $1 ] ; then
  /usr/sbin/adduser --gecos "" $1
  /bin/chmod 0750 /home/$1
else
  echo "Usage: secadd.sh username"
fi

/root/webadd.sh

#!/bin/sh
# This still doesn't do everything it should. Need to flesh it out more.
if [ $1 ] && [ $2 ] && [ $3 ] ; then
 export KEYFILE="/etc/certs/$2.key"
 export CSRFILE="/etc/certs/$2.csr"
 /usr/bin/openssl genrsa -out $KEYFILE 4096
 /bin/chmod 0600 $KEYFILE
 /bin/sed -e "s/DOMAIN/$2/g" /root/csr.cnf > /root/csr$2.cnf
 /usr/bin/openssl req -new -config /root/csr$2.cnf -key $KEYFILE -out $CSRFILE
 /usr/sbin/adduser --shell /usr/sbin/nologin --disabled-password --gecos "" --conf /etc/webuser.conf $1
 /usr/sbin/usermod -a -G website $1
 /usr/bin/mkdir /var/log/$2
 /bin/chmod 0750 /var/log/$2
 /bin/chown $1:adm /var/log/$2
 /usr/bin/ln -sv /var/log/$2 /home/$1/logs
 /bin/sed "s/USERNAME/$1/g; s/DOMAIN/$2/g; s/IPADDRESS/$3/g" /root/fpmnginx.conf > /etc/nginx/sites/$1.conf
 /bin/sed "s/USERNAME/$1/" /root/php-fpm.7.4.conf > /home/$1/pool/$2.conf
 /bin/sed "s/USERNAME/$1/" /root/php-logrotate.template > /etc/logrotate.d/php-$1
 /bin/sed "s/USERNAME/$1/g; s/DOMAIN/$2/g" /root/php7.4-fpm.service.template > /etc/systemd/system/multi-user.target.wants/fpm-$2.service
 /bin/chmod 0751 /home/$1
 /bin/chown root /home/$1
 /bin/chown root /home/$1/.ssh
 /bin/chown root /home/$1/.ssh/authorized_keys
 /bin/chgrp www-data /home/$1/docs
 /bin/chgrp www-data /home/$1/sock
 /usr/bin/systemctl start fpm-$2.service
else
 echo "Usage: webadd.sh username domain ipaddress"
fi

This makes use of the templates we make in other parts of the guide, applying them accordingly.

A few go here:

/root/php-logrotate.template

/var/log/USERNAME/*.log {
       rotate 26
       weekly
       missingok
       notifempty
       create 0640 USERNAME adm
       compress
       delaycompress
       postrotate
               kill -USR1 $(cat /home/USERNAME/pool/fpm-USERNAME.pid) > /dev/null
       endscript
}

/root/csr.cnf

# Template file for automagic csr generation.
# Import domain name
FQDN = DOMAIN
# the name of your organization
ORGNAME = myorgname
# Mainly for www. but can add others, of course.
ALTNAMES = DNS:$FQDN, DNS:www.$FQDN # , DNS:bar.$FQDN , DNS:www.foo.$FQDN
[ req ]
default_bits = 4096
default_md = sha256
prompt = no
encrypt_key = no
distinguished_name = dn
req_extensions = req_ext
[ dn ]
C = US
O = $ORGNAME
CN = $FQDN
[ req_ext ]
subjectAltName = $ALTNAMES