Notes on systemd

courtesy of chatgpt

The sudo systemctl enable command is used to configure a system service to start automatically at boot. It does this by creating symbolic links for the service in the appropriate system directories.


How It Works

When you run:

sudo systemctl enable <service-name>
  1. Locates the Service File:

    • The system searches for the service’s unit file, typically located in /etc/systemd/system/ or /lib/systemd/system/.
  2. Creates Symbolic Links:

    • It creates symbolic links from the unit file to the appropriate directories under /etc/systemd/system/, such as:
      • /etc/systemd/system/multi-user.target.wants/ (for most services).
      • /etc/systemd/system/graphical.target.wants/ (for graphical services).
  3. Ensures Auto-Start:

    • These symbolic links make the service start automatically when the corresponding target is reached during the system boot process.

Key Points

  • Does Not Start the Service: Enabling a service does not start it immediately. To start the service right away, use:

    sudo systemctl start <service-name>
    
  • Persistent Across Reboots: Once enabled, the service will automatically start whenever the system reboots.

  • Reversible: To disable auto-start, run:

    sudo systemctl disable <service-name>
    

Example

  1. Enable a web server (e.g., Apache):

    sudo systemctl enable apache2
    
  2. Verify the symbolic link:

    ls -l /etc/systemd/system/multi-user.target.wants/apache2.service
    
  3. Start the service immediately:

    sudo systemctl start apache2
    

Related Commands

  • Start a Service Immediately:

    sudo systemctl start <service-name>
    
  • Check If a Service Is Enabled:

    systemctl is-enabled <service-name>
    
  • View Service Status:

    sudo systemctl status <service-name>
    
  • Disable a Service:

    sudo systemctl disable <service-name>
    

When to Use enable

Use enable for services you want to start automatically on boot, such as:

  • Web servers (e.g., Apache, Nginx).
  • Databases (e.g., MySQL, PostgreSQL).
  • Background services (e.g., Docker, SSH).

Best practices on creating user account

When creating a user account for a service in Linux, there are several considerations to ensure the account is secure, functional, and follows best practices. Here’s what you should keep in mind:


Key Considerations

1. Non-Interactive Account

  • A service account typically doesn’t need interactive login capabilities.
  • Set the shell to /usr/sbin/nologin or /bin/false to disable login:
    sudo useradd -r -s /usr/sbin/nologin serviceuser
    
    This prevents the service account from being used for interactive logins.

2. System User vs Regular User

  • Use the -r option with useradd to create a system account (UID below 1000 on most systems):
    sudo useradd -r serviceuser
    
    System accounts are intended for system-level services and are typically excluded from login screens.

3. No Password

  • A service account usually doesn’t need a password. Do not set one:
    sudo useradd -r -s /usr/sbin/nologin serviceuser
    
    This avoids potential misuse of the account.

4. Restrict Access

  • Ensure the service account has limited permissions, restricted to what the service needs.
  • If the service requires file access, set appropriate ownership and permissions:
    sudo chown -R serviceuser:servicegroup /path/to/service/files
    sudo chmod -R 750 /path/to/service/files
    

5. Minimal Privileges

  • Follow the principle of least privilege:
    • Only grant the permissions and group memberships that the service needs.
    • Avoid adding the service account to privileged groups like sudo unless necessary.

6. Environment Variables

  • If the service requires specific environment variables, you can define them in a service-specific environment file or the service’s systemd unit file instead of relying on .bashrc or .profile.

Example of setting environment variables in a systemd service file:

[Service]
Environment="VAR_NAME=value"
EnvironmentFile=/etc/serviceuser/envfile

7. Home Directory

  • Service accounts usually don’t need a home directory. Use the -M option with useradd to skip creating one:

    sudo useradd -r -M serviceuser
    
  • If the service needs a home directory for configuration or storage, specify it explicitly:

    sudo useradd -r -d /var/lib/serviceuser serviceuser
    sudo mkdir -p /var/lib/serviceuser
    sudo chown serviceuser:servicegroup /var/lib/serviceuser
    

8. Systemd Integration

  • For services managed by systemd, you can specify the user account in the service unit file:
    [Service]
    User=serviceuser
    Group=servicegroup
    
    This ensures the service runs under the correct account.

9. Logging

  • Ensure the service account has appropriate access to its log directory:
    sudo mkdir -p /var/log/servicename
    sudo chown serviceuser:servicegroup /var/log/servicename
    

10. Audit and Monitoring

  • Keep track of the service account’s activity:
    • Log any changes to the account using audit tools like auditd.
    • Monitor the service process to ensure it doesn’t escalate privileges or behave unexpectedly.

Sample Command to Create a Service Account

sudo useradd -r -M -s /usr/sbin/nologin -d /var/lib/serviceuser -c "Service account for MyService" serviceuser

Explanation:

  • -r: Create a system account.
  • -M: Do not create a home directory.
  • -s /usr/sbin/nologin: Disable shell login.
  • -d /var/lib/serviceuser: Specify a custom home directory (optional).
  • -c: Add a comment describing the account.

Does systemctl stop send a kill -9 signal to stop the process?

No, systemctl stop does not send a SIGKILL (kill -9) by default. Instead, it typically sends a SIGTERM signal to the process to allow it to shut down gracefully. The process has a limited amount of time (defined by the TimeoutStopSec in the unit file, defaulting to 90 seconds) to clean up and exit after receiving the SIGTERM.

If the process does not stop within that time, systemd will escalate by sending a SIGKILL to forcibly terminate it.

Here’s the sequence:

  1. SIGTERM is sent to give the process a chance to stop gracefully.
  2. If the process doesn’t stop within the timeout (TimeoutStopSec), SIGKILL is sent to forcefully terminate it.

You can adjust these behaviors in the service unit file by setting:

  • KillSignal=TERM (or another signal if you want something other than SIGTERM)
  • TimeoutStopSec=30s (or any desired timeout duration)

For example, you can inspect these settings with:

systemctl show your-service-name | grep -i kill

This will display the signal and timeout configurations for the service.

Does spring webflux behave nicely with SIGTERM?

Yes, Spring WebFlux behaves well with SIGTERM signals and can be gracefully shut down when configured properly. Here’s how it works and what you need to do to ensure a smooth shutdown:

Key Points about WebFlux and SIGTERM

  1. Reactive Nature:
    WebFlux is based on a reactive programming model, so it handles requests in a non-blocking, asynchronous manner. This makes it well-suited for environments like Kubernetes or Docker, where SIGTERM is commonly used to signal a graceful shutdown.

  2. Graceful Shutdown Process: When a SIGTERM is received, the application can stop accepting new requests, finish processing in-flight requests, and release resources such as database connections and thread pools.

  3. Steps for Proper Handling of SIGTERM:

    a. Enable Graceful Shutdown in Spring Boot:
    Spring Boot (starting from version 2.3) provides built-in support for graceful shutdown. You need to enable it by setting the following property in your application.properties or application.yml:

    server.shutdown=graceful
    

    b. Customize Shutdown Behavior:
    Implement cleanup logic using DisposableBean or @PreDestroy annotations in your beans. For example:

    @PreDestroy
    public void cleanUp() {
        System.out.println("Releasing resources...");
        // Close connections, stop background tasks, etc.
    }
    

    c. Manage In-Flight Requests:
    When SIGTERM is received, Spring will stop accepting new requests but allow in-flight requests to complete. This ensures no abrupt termination of active requests.

  4. Reactive Components and Cancellation:
    Ensure that reactive components (e.g., Mono or Flux) correctly handle cancellation signals, which may occur during shutdown.

  5. Timeout Considerations:

    • The shutdown timeout is governed by the spring.lifecycle.timeout-per-shutdown-phase property (default is 30 seconds). You can adjust it based on your application’s needs:
      spring.lifecycle.timeout-per-shutdown-phase=60s
      
  6. Deployment Considerations:

    • In containerized environments like Kubernetes, configure proper readiness and liveness probes to ensure that the application isn’t terminated prematurely and has time to shut down gracefully.

Example of Graceful Shutdown

Here’s a complete example:

import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;

@Component
public class CleanupComponent {

    @PreDestroy
    public void onShutdown() {
        System.out.println("Application is shutting down. Cleaning up resources...");
        // Perform any cleanup logic here
    }
}

By combining these techniques, you can ensure that Spring WebFlux applications handle SIGTERM gracefully and avoid abrupt disruptions during shutdown.

This entry was posted in Uncategorized and tagged , , , , . Bookmark the permalink.

Leave a comment