Search

GNU Linux Security

0 views

Establishing a Comprehensive Security Policy

Before you tweak any kernel flags or edit configuration files, set a clear security policy that matches your organization’s risk appetite and compliance requirements. A well‑defined policy tells you exactly what data or services need protection, who is allowed to access them, and what the response should be when a violation occurs. Without it, every hardening step you take feels arbitrary and can create gaps that attackers exploit later. Start by cataloguing the assets you host on Linux: web servers, databases, file shares, and internal tools. Then assign each asset a sensitivity level - public, internal, or confidential - and map that to a set of controls. The policy should cover account creation, password management, privileged access, patching cadence, audit logging, and incident handling. A useful reference is the “Security Handbook” (RFC 2196) which offers a practical framework for policy development. Once the policy is drafted, circulate it for review, and ensure that every administrator knows where to find it and how to follow it when adding new services or modifying existing ones.

During the policy design phase, ask yourself how you will enforce compliance. Decide which tools will collect logs, how often you’ll review them, and who will own the audit trail. Include a section on package management: because GNU/Linux distributions ship thousands of packages, you need to vet which of them are required for production. In many cases, removing unnecessary packages eliminates a large attack surface. Keep a running inventory and review it whenever a new package is installed or an existing one is upgraded. The policy should also define when and how you perform vulnerability scanning, patching, and system backups. By embedding these rules in a formal document, you reduce the chance of ad‑hoc changes that compromise security.

The policy must also dictate how you respond to incidents. Specify the escalation path for alerts, the communication channels for internal stakeholders, and the documentation required for post‑mortem analysis. In environments where regulations apply - HIPAA, PCI‑DSS, or GDPR - your policy should reflect the legal obligations for data protection. By documenting all these expectations, you provide a single source of truth that guides every administrator’s actions and makes the organization auditable.

When you’re satisfied with the policy draft, test it in a sandbox environment. Apply the rules to a replica of your production system and confirm that the hardening steps actually improve security without breaking functionality. This simulation will expose any blind spots and give you confidence that the policy works in practice. Once the policy is finalized and tested, lock it into a version‑controlled repository and enforce it with configuration‑management tools like Ansible, Puppet, or Chef. That way, any deviation from the policy can be detected and corrected automatically.

Remember that a security policy is a living document. Schedule regular reviews - at least annually or after major changes - to keep it relevant. Each review should include a risk assessment and an update of the controls if new threats or technologies emerge. By treating the policy as a dynamic asset, you keep the security posture strong and responsive to evolving threats.

Strengthening User Accounts, Passwords, and Root Handling

In Linux, the strength of user accounts directly impacts overall security. Begin by removing unused or default accounts such as adm, operator, or guest. Running userdel and groupdel on these accounts cleans up the namespace and limits the number of potential attack vectors. After deletion, set the immutable flag on key files that control authentication: /etc/passwd, /etc/shadow, /etc/group, and /etc/gshadow. Use chattr +i on each file; if you need to edit them later, first drop the immutable attribute with chattr -i. This practice protects against unauthorized edits that could elevate privileges or bypass password checks.

Passwords are the first line of defense. Enforce a policy that requires alphanumeric passwords of at least twelve characters, combining upper and lower case letters, digits, and symbols. Avoid predictable patterns such as birth dates or usernames. Enable password expiration every ninety days and configure the system to lock an account after three failed login attempts. Add the following to /etc/login.defs:

Prompt
PASS_MAX_DAYS 90</p> <p>PASS_MIN_DAYS 0</p> <p>PASS_WARN_AGE 7</p> <p>FAIL_DELAY 3</p>

These settings force regular password changes and introduce a delay after successive failures, which slows brute‑force attempts. In addition, turn on PAM modules that provide account lockout and auditing, such as pam_faillock. This module tracks failed attempts per user or per IP and automatically locks the account or blocks the IP after a threshold is reached.

For the root account, adopt the principle of least privilege. Disable direct root logins over SSH by editing /etc/ssh/sshd_config:

Prompt
PermitRootLogin no</p>

Instead, create a regular administrative user, grant it sudo privileges, and require the user to authenticate with their own password before any privileged command is executed. This keeps the root password out of reach while still allowing necessary tasks. To further reduce risk, configure session timeouts. Add the following to /etc/profile:

Prompt
TMOUT=1800</p> <p>readonly TMOUT</p>

When a user remains idle for thirty minutes, the shell will automatically log them out. Combine this with the HISTSIZE and HISTFILESIZE settings to limit command history size and zero it upon logout, reducing the risk of sensitive data exposure through the history file.

Enable two‑factor authentication for any critical accounts that will perform administrative tasks. Configure PAM to use Google Authenticator or similar solutions, ensuring that even if a password is compromised, the attacker still faces a second hurdle. For remote access, prefer key‑based authentication over passwords entirely. Generate SSH keys with at least 4096‑bit RSA or ECDSA, store the private key securely, and distribute only the public key to the servers. Disable password authentication in sshd_config to enforce this method.

Finally, conduct periodic reviews of the user database. Use tools like lastlog and awk scripts to identify inactive accounts and delete them. Automate this cleanup in your configuration management pipeline to maintain a lean user base. By tightening account controls, you reduce the attack surface and make it harder for attackers to gain persistence through stolen credentials.

Bootloader, Kernel, and Session Safeguards

Secure boot and kernel configuration are often overlooked but critical to system integrity. Start by locking down the bootloader. If you use LILO, edit /etc/lilo.conf to disable the boot prompt and set a password for kernel parameter editing. Add the following lines:

Prompt
timeout=00</p> <p>password=YOUR_PASSWORD</p> <p>restricted</p>

After editing, update permissions: chmod 600 /etc/lilo.conf. Run /sbin/lilo -v to apply changes. To make the file immutable, use chattr +i /etc/lilo.conf so no accidental modifications can occur. Remember to remove the immutable flag before you need to adjust boot options again.

For systems using GRUB, create a password‑protected GRUB configuration. In /etc/grub.d/40_custom, add:

Prompt
set superusers="admin"</p> <p>password_pbkdf2 admin grub.pbkdf2.sha512.10000.XXXXXXXXXXXXXXXXXXXX</p>

Replace the hash with one generated via grub-mkpasswd-pbkdf2. This restricts access to kernel arguments and initramfs tweaks, protecting against malicious tampering during boot.

Prevent unauthorized single‑user mode access by editing /etc/inittab. Add the following line to enforce a password prompt when attempting to enter single‑user mode:

Prompt
id:3:initdefault:</p> <p>~~:S:wait:/sbin/sulogin</p>

Then run /sbin/init q to reload the configuration. This change forces an interactive login before the system can be booted into maintenance mode, mitigating the risk of a local attacker resetting root passwords or altering critical files during downtime.

Disable the Ctrl‑Alt‑Del reboot shortcut, which can be abused to trigger accidental reboots. Edit /etc/inittab and comment out the line:

Prompt
#ca::ctrlaltdel:/sbin/shutdown -t3 -r now</p>

Run /sbin/init q again. Additionally, lock /etc/services with chattr +i /etc/services to prevent tampering with network service definitions.

Protect session integrity by setting strict permissions on the init scripts. Make all /etc/init.d files executable only by root: chmod -R 700 /etc/init.d/*. This ensures that no unprivileged user can add or modify startup services. Likewise, set /bin/rpm to chmod 700 so that only root can manage packages, preventing attackers from installing malicious RPMs.

Configure the kernel to log all boot and run‑time events. In /etc/sysctl.conf, add:

Prompt
kernel.kptr_restrict = 2</p> <p>kernel.perf_event_paranoid = 3</p> <p>vm.mmap_min_addr = 65536</p>

These settings reduce the exposure of kernel pointers, limit the use of performance counters, and restrict memory mapping from unprivileged processes. Reload sysctl with sysctl -p. By tightening kernel parameters, you close several attack vectors that rely on kernel exploitation.

File System Permissions, Immutable Files, and Continuous Auditing

Secure file permissions are the backbone of Linux security. First, audit the system for SUID and SGID files, which can be abused if compromised. Run:

Prompt
find / -type f \( -perm -04000 -o -perm -02000 \) -exec ls -l {} \; > SUID_SGID_files.txt</p>

Review this list manually. Any file that shouldn't be privileged should have its SUID/SGID bits cleared with chmod -s or chmod -g. Maintain a baseline by storing this file in version control; any deviation can signal a breach.

Look for world‑writable or group‑writable files and directories, which can be modified by non‑privileged users. Identify them with:

Prompt
find / -type f \( -perm -2 -o -perm -20 \) -exec ls -lg {} \;</p> <p>find / -type d \( -perm -2 -o -perm -20 \) -exec ls -ldg {} \;</p>

After listing, remediate by setting stricter permissions: chmod 644 for files, chmod 755 for directories. Ensure that configuration files containing secrets are set to chmod 600 and owned by root. Automate this with a cron job that checks for world‑writable files and alerts an admin.

Detect unowned files that might be leftovers from broken packages or rogue processes. Run:

Prompt
find / -nouser -o -nogroup</p>

Remove or re‑own these files. Unowned files can be used by attackers to hide malicious payloads. Set chown root:root on them and adjust permissions accordingly.

Remove unnecessary banner files that could leak system information. Delete /etc/issue and /etc/issue.net if you don't need them. A blank banner or a generic message reduces the data an attacker can gather during SSH or console logins.

Enable auditd to capture critical events such as file modifications, privilege escalation, and login attempts. Install the audit daemon and configure a ruleset that watches sensitive directories:

Prompt
auditctl -w /etc/shadow -p wa</p> <p>auditctl -w /etc/passwd -p wa</p> <p>auditctl -w /var/log/ -p wa</p>

Set up an automated log‑rotate script that compresses and removes old logs older than 30 days, preventing disk exhaustion attacks. Additionally, forward audit logs to a remote SIEM or log‑analysis server so you can detect anomalies in near real time.

Periodic integrity checks using tripwire or AIDE provide another layer of defense. Initialize a baseline database:

Prompt
aideinit</p>

Then schedule daily checks with:

Prompt
aide --check > /var/log/aide/aide.log</p>

Any mismatch between the current file state and the baseline should trigger an alert. This process catches unauthorized changes, such as a trojan modifying a binary or an attacker adding a malicious cron job.

Finally, enforce that all critical configuration files are owned by root and have immutable attributes. For example:

Prompt
chattr +i /etc/ssh/sshd_config</p> <p>chattr +i /etc/sysctl.conf</p>

With these measures in place - tight file permissions, immutable flags, continuous auditing, and integrity monitoring - the system’s attack surface is substantially reduced. Coupled with the earlier policy and account hardening steps, you create a robust security posture that resists both external and internal threats.

Suggest a Correction

Found an error or have a suggestion? Let us know and we'll review it.

Share this article

Comments (0)

Please sign in to leave a comment.

No comments yet. Be the first to comment!

Related Articles