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


9 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