Newsletter
TechAnV Blog
Get updates on security engineering, Rust, eBPF, and DevSecOps. No spam, unsubscribe anytime.
Check your inbox and click the confirmation link to complete your subscription.
Running OpenSearch in Rootless Podman Containers#
Modern infrastructure demands robust security practices, and running containers with reduced privileges is a key component of defense-in-depth strategies. This guide demonstrates how to run OpenSearch in rootless Podman containers with proper systemd integration, enabling powerful search capabilities without requiring root privileges.
Why Rootless Containers?#
Rootless containers provide several security benefits:
- Reduced attack surface - compromised containers can’t easily escalate to root privileges
- User namespace isolation - containers run with regular user privileges
- Improved security posture - follows the principle of least privilege
- Regulatory compliance - helps meet security requirements in regulated environments
Prerequisites#
Before starting, ensure you have:
- Linux system with Podman 3.0+ installed
- systemd user service support
- At least 2GB of available RAM (4GB+ recommended for production)
- Appropriate kernel settings (covered below)
Step 1: System Preparation#
First, we’ll configure the necessary kernel parameters to allow for ElasticSearch-like applications in rootless containers:
1# Create a sysctl configuration file2cat << EOF | sudo tee /etc/sysctl.d/99-opensearch.conf3vm.max_map_count=2621444fs.file-max=655365EOF6
7# Apply the settings8sudo sysctl --systemStep 2: Create Data Directory#
Create a persistent storage location for OpenSearch data:
1mkdir -p ~/.local/share/opensearch-data2chmod 700 ~/.local/share/opensearch-dataStep 3: Create systemd Service File#
Create a systemd user service file to manage the OpenSearch container:
1mkdir -p ~/.config/systemd/user/2cat << EOF > ~/.config/systemd/user/container-opensearch-node1.service3[Unit]4Description=Podman container-opensearch-node1.service5Documentation=man:podman-generate-systemd(1)6Wants=network-online.target7After=network-online.target8RequiresMountsFor=%t/containers9
10[Service]11Environment=PODMAN_SYSTEMD_UNIT=%n12Restart=on-failure13TimeoutStopSec=7014ExecStartPre=/bin/rm -f %t/%n.ctr-id15ExecStart=/usr/bin/podman run \\16 --cidfile=%t/%n.ctr-id \\17 --cgroups=no-conmon \\18 --rm \\19 --sdnotify=conmon \\20 --replace \\21 -d \\22 --name opensearch-node1 \\23 -e cluster.name=opensearch-cluster \\24 -e node.name=opensearch-node1 \\25 -e discovery.type=single-node \\26 -e "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" \\27 -e OPENSEARCH_INITIAL_ADMIN_PASSWORD=Anubhav@321 \\28 -e DISABLE_INSTALL_DEMO_CONFIG=false \\29 -e DISABLE_SECURITY_PLUGIN=false \\30 -e bootstrap.memory_lock=false \\31 --ulimit nofile=65536:65536 \\32 -v $HOME/.local/share/opensearch-data:/usr/share/opensearch/data:Z,rw \\33 -p 9200:9200 \\34 -p 9600:9600 \\35 --user $(id -u):$(id -g) \\36 docker.io/opensearchproject/opensearch:latest37
38ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id39ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id40Type=notify41NotifyAccess=all42
43[Install]44WantedBy=default.target45EOFStep 4: Enable and Start the Service#
Now let’s enable and start our OpenSearch service:
1# Reload systemd configuration2systemctl --user daemon-reload3
4# Enable the service to start at login5systemctl --user enable container-opensearch-node1.service6
7# Start the service8systemctl --user start container-opensearch-node1.service9
10# Enable lingering to allow the service to run without being logged in11loginctl enable-linger $(whoami)Step 5: Verify the Deployment#
After giving OpenSearch about 30-45 seconds to initialize, verify that it’s running correctly:
1# Check service status2systemctl --user status container-opensearch-node1.service3
4# Test HTTPS endpoint with admin credentials5curl -k -u admin:Anubhav@321 https://localhost:9200/_cluster/healthYou should see output similar to:
1{2 "cluster_name": "opensearch-cluster",3 "status": "green",4 "timed_out": false,5 "number_of_nodes": 1,6 "number_of_data_nodes": 1,7 "discovered_master": true,8 "active_primary_shards": 1,9 "active_shards": 1,10 "relocating_shards": 0,11 "initializing_shards": 0,12 "unassigned_shards": 0,13 "delayed_unassigned_shards": 0,14 "number_of_pending_tasks": 0,15 "number_of_in_flight_fetch": 0,16 "task_max_waiting_in_queue_millis": 0,17 "active_shards_percent_as_number": 100.018}Understanding the systemd Service Configuration#
Let’s break down the key parts of our service file: