How to Create Restricted Service Accounts for Tomcat/Nginx/PostgreSQL on Debian Server with No Shell Access


45 views

When setting up production servers, it's crucial to follow security best practices by creating dedicated users for each service. This isolation prevents privilege escalation attacks where a compromised service could access other system components.

For Debian-based systems (including Squeeze), the standard method involves:

sudo adduser --system --group --no-create-home --shell /usr/sbin/nologin tomcat
sudo adduser --system --group --no-create-home --shell /usr/sbin/nologin nginx
sudo adduser --system --group --no-create-home --shell /usr/sbin/nologin postgres

Beyond basic user creation, implement these restrictions:

# Set immutable home directory (even if not used)
sudo chattr +i /nonexistent

# Restrict service capabilities
sudo setcap -r /usr/lib/postgresql/11/bin/* 2>/dev/null

# Create individual apparmor profiles for each service
sudo aa-genprof /usr/sbin/tomcat

For maximum security, consider these directory structures:

# Nginx example
sudo mkdir -p /srv/nginx/{logs,temp,conf}
sudo chown -R nginx:nginx /srv/nginx
sudo chmod 750 /srv/nginx

Check your setup with these commands:

# Verify shell restriction
getent passwd tomcat | cut -d: -f7

# Check process ownership
ps aux | grep -E 'tomcat|nginx|postgres'

If services fail to start:

# Check for permission errors
sudo -u tomcat /path/to/tomcat/bin/startup.sh

# Verify directory ownership
namei -l /var/lib/tomcat/webapps

For modern Debian systems using systemd:

[Service]
User=tomcat
Group=tomcat
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full

When deploying critical services like Tomcat, Nginx, and PostgreSQL on Debian, creating dedicated system users is a fundamental security practice. These accounts should have:

  • No interactive shell access
  • Minimal filesystem permissions
  • Ownership of only necessary resources

The most secure approach combines useradd with proper shell restrictions:

# First, ensure nologin is a valid shell
if ! grep -q "/usr/sbin/nologin" /etc/shells; then
    echo "/usr/sbin/nologin" >> /etc/shells
fi

# Create user with locked down permissions
sudo useradd -r -s /usr/sbin/nologin -d /nonexistent -M tomcat
sudo useradd -r -s /usr/sbin/nologin -d /nonexistent -M nginx
sudo useradd -r -s /usr/sbin/nologin -d /nonexistent -M postgres

Key parameters explained:

  • -r: Creates a system account
  • -s /usr/sbin/nologin: Prevents shell access
  • -d /nonexistent: No home directory
  • -M: Don't create home directory

For additional security, implement filesystem restrictions:

# Create secure directories with proper ownership
sudo mkdir -p /var/lib/tomcat
sudo chown tomcat:tomcat /var/lib/tomcat
sudo chmod 750 /var/lib/tomcat

# Set up apparmor profiles for service isolation
sudo apt-get install apparmor apparmor-utils
sudo aa-genprof tomcat

For Nginx:

sudo useradd -r -s /usr/sbin/nologin -d /var/lib/nginx -M nginx
sudo mkdir -p /var/lib/nginx/tmp
sudo chown -R nginx:nginx /var/lib/nginx
sudo chmod -R 750 /var/lib/nginx

For PostgreSQL:

sudo useradd -r -s /bin/bash -d /var/lib/postgresql -M postgres
sudo mkdir -p /var/lib/postgresql/data
sudo chown -R postgres:postgres /var/lib/postgresql
sudo chmod -R 700 /var/lib/postgresql

Check your configuration with:

# Verify shell access is blocked
sudo -u tomcat /usr/sbin/nologin

# Check account details
grep 'tomcat\|nginx\|postgres' /etc/passwd

# Verify directory permissions
ls -ld /var/lib/tomcat
ls -la /var/lib/tomcat

For reproducible deployments, use Ansible:

- name: Create secure service accounts
  user:
    name: "{{ item }}"
    shell: /usr/sbin/nologin
    home: /nonexistent
    create_home: no
    system: yes
  loop:
    - tomcat
    - nginx
    - supervisor

If services fail to start:

  • Check /var/log/syslog for permission errors
  • Verify proper SELinux/AppArmor contexts
  • Ensure required directories exist with correct ownership