Instalasi di CentOS / RHEL #
Sistem operasi berbasis Red Hat — RHEL, CentOS, Rocky Linux, AlmaLinux, dan Fedora — memiliki karakteristik keamanan yang berbeda dari Ubuntu/Debian. Dua hal yang paling membedakan dan paling sering menjadi sumber masalah adalah SELinux dan firewalld. Keduanya aktif secara default dan keduanya akan memblokir Caddy dari berfungsi dengan benar jika tidak dikonfigurasi dengan tepat.
Artikel ini membahas instalasi Caddy di seluruh distribusi berbasis RPM, dengan penekanan khusus pada konfigurasi SELinux yang benar — bukan cara pintas yang menonaktifkan SELinux, yang adalah praktik buruk yang merusak keamanan sistem.
Distribusi yang Didukung #
Panduan ini berlaku untuk:
Distribusi Versi yang Didukung
─────────────────────────────────────────────────
Fedora 38, 39, 40+
CentOS Stream 8, 9
RHEL 8, 9
Rocky Linux 8, 9
AlmaLinux 8, 9
Oracle Linux 8, 9
Untuk CentOS 7 / RHEL 7, prosesnya sedikit berbeda karena menggunakan yum bukan dnf. Catatan khusus untuk CentOS 7 disertakan di bagian tersendiri.
Instalasi via COPR Repository #
Caddy menggunakan COPR (Cool Other Package Repo) — sistem repository komunitas Red Hat yang mirip dengan PPA di Ubuntu — sebagai distribution channel resmi untuk ekosistem RPM.
Fedora #
# Fedora sudah include dnf copr plugin secara default
sudo dnf copr enable @caddy/caddy
sudo dnf install caddy
CentOS Stream / RHEL / Rocky Linux / AlmaLinux (versi 8 dan 9) #
# Step 1: Install dnf copr plugin jika belum ada
sudo dnf install -y 'dnf-command(copr)'
# Step 2: Tambahkan repository Caddy
sudo dnf copr enable @caddy/caddy
# Kamu akan ditanya konfirmasi — ketik 'y'
# Step 3: Install Caddy
sudo dnf install caddy
# Verifikasi instalasi
caddy version
CentOS 7 / RHEL 7 (Legacy) #
# Gunakan yum untuk sistem lama
sudo yum install yum-plugin-copr
sudo yum copr enable @caddy/caddy
sudo yum install caddy
CentOS 7 sudah end-of-life pada Juni 2024. RHEL 7 juga sudah masuk fase Extended Life Cycle Support. Sangat disarankan untuk migrasi ke Rocky Linux 9 atau AlmaLinux 9 sebelum melanjutkan deployment Caddy baru.
Memahami dan Mengkonfigurasi SELinux #
SELinux (Security-Enhanced Linux) adalah sistem mandatory access control yang menambahkan lapisan keamanan di atas permission Unix standar. Di RHEL dan distribusi turunannya, SELinux aktif dalam mode enforcing secara default — artinya ia secara aktif memblokir operasi yang tidak diizinkan policy.
Banyak tutorial menyarankan untuk menonaktifkan SELinux saat mengalami masalah. Ini adalah saran yang sangat buruk dan kamu harus menghindarinya. SELinux memberikan perlindungan nyata terhadap berbagai vektor serangan — bahkan jika aplikasi kamu mengalami RCE (Remote Code Execution), SELinux membatasi apa yang bisa dilakukan oleh attacker.
Solusi yang benar adalah mengkonfigurasi SELinux agar mengizinkan operasi yang Caddy butuhkan.
Memahami Mode SELinux #
# Cek mode SELinux saat ini
getenforce
# Output: Enforcing (aktif memblokir)
# atau: Permissive (log tapi tidak blokir)
# atau: Disabled (nonaktif)
# Cek konfigurasi dari file
cat /etc/selinux/config
# Ganti ke Permissive sementara untuk troubleshooting (JANGAN di production)
# sudo setenforce 0
# Kembali ke Enforcing
# sudo setenforce 1
Konfigurasi Boolean SELinux untuk Caddy #
SELinux Boolean adalah switch on/off yang mengontrol aspek tertentu dari policy SELinux tanpa perlu menulis policy kustom. Untuk Caddy, ada beberapa boolean yang perlu dikonfigurasi:
# Boolean 1: Izinkan proses web (httpd-like) membuat koneksi jaringan
# Diperlukan untuk: reverse_proxy, ACME challenge ke Let's Encrypt
sudo setsebool -P httpd_can_network_connect 1
# Boolean 2: Izinkan proses web melakukan relay koneksi
# Diperlukan untuk: reverse proxy ke backend
sudo setsebool -P httpd_can_network_relay 1
# Boolean 3: Izinkan proses web terhubung ke database
# Diperlukan jika: backend app langsung query DB melalui Caddy (jarang)
# sudo setsebool -P httpd_can_network_connect_db 1
# Verifikasi boolean sudah aktif
getsebool httpd_can_network_connect
getsebool httpd_can_network_relay
# Output yang diharapkan:
# httpd_can_network_connect --> on
# httpd_can_network_relay --> on
Flag -P pada setsebool berarti persistent — perubahan ini tetap ada setelah reboot. Tanpa -P, perubahan hanya berlaku sampai server di-restart.
Konfigurasi File Context untuk Webroot #
Jika webroot kamu ada di lokasi yang tidak standar (bukan /var/www/html), SELinux akan memblokir Caddy dari membaca file tersebut karena context yang salah.
# Cek context SELinux dari direktori webroot
ls -lZ /var/www/html
# Output: drwxr-xr-x. caddy caddy unconfined_u:object_r:httpd_sys_content_t:s0 html
# "httpd_sys_content_t" adalah context yang diperlukan untuk file yang
# bisa dibaca oleh proses web (httpd, caddy, nginx, dsb)
# Jika webroot ada di lokasi kustom, set context yang benar:
sudo chcon -Rt httpd_sys_content_t /path/to/custom/webroot
# Atau menggunakan semanage untuk perubahan yang persisten
# (lebih disarankan karena bertahan setelah restorecon)
sudo semanage fcontext -a -t httpd_sys_content_t "/path/to/webroot(/.*)?"
sudo restorecon -Rv /path/to/webroot
Troubleshooting SELinux Denial #
Ketika SELinux memblokir operasi, ia mencatat AVC denial (Access Vector Cache denial) di audit log. Ini adalah cara untuk mendiagnosis apa yang diblokir dan mengapa.
# Lihat AVC denial terbaru
sudo ausearch -m avc -ts recent
# Lihat dengan format yang lebih mudah dibaca
sudo ausearch -m avc -ts recent | audit2why
# Contoh output audit2why:
# type=AVC msg=audit(1234567890.123:456): avc: denied { name_connect }
# for pid=1234 comm="caddy" dest=443 scontext=system_u:system_r:httpd_t:s0
# tcontext=system_u:object_r:http_cache_port_t:s0 tclass=tcp_socket permissive=0
#
# Was caused by:
# Missing type enforcement (TE) allow rule.
# You can use audit2allow to generate a loadable module to allow this access.
# Untuk melihat semua AVC denial hari ini
sudo ausearch -m avc -ts today
# Install audit tools jika belum ada
sudo dnf install audit policycoreutils-python-utils
Membuat Policy Kustom (Jika Boolean Tidak Cukup) #
Untuk kasus yang lebih spesifik di mana boolean standar tidak mencukupi:
# Generate policy module dari AVC denial yang ada
sudo ausearch -m avc -ts recent | audit2allow -M caddy-custom
# Review policy yang akan dibuat (PENTING — review sebelum apply)
cat caddy-custom.te
# Install policy module
sudo semodule -i caddy-custom.pp
# Verifikasi module terinstall
sudo semodule -l | grep caddy
Mengkonfigurasi Firewalld #
Firewalld adalah firewall default di RHEL dan distribusi turunannya. Berbeda dengan ufw di Ubuntu, firewalld menggunakan konsep zones — setiap interface jaringan dikaitkan dengan zone yang memiliki policy berbeda.
Konsep Zone Firewalld #
Zone yang umum digunakan:
public → Default untuk interface publik
internal → Interface jaringan internal
trusted → Semua koneksi diizinkan
Cek zone aktif
# Cek zone default
sudo firewall-cmd --get-default-zone
# Biasanya output: public
# Cek zone aktif untuk setiap interface
sudo firewall-cmd --get-active-zones
# Lihat semua rule di zone public
sudo firewall-cmd --zone=public --list-all
Membuka Port untuk Caddy #
# Cara 1: Menggunakan service yang sudah terdefinisi (direkomendasikan)
# Lebih deskriptif dan portable antar sistem
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
# Cara 2: Menggunakan nomor port langsung
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --permanent --add-port=443/udp # HTTP/3
# PENTING: Reload firewalld untuk menerapkan perubahan --permanent
sudo firewall-cmd --reload
# Verifikasi port sudah terbuka
sudo firewall-cmd --zone=public --list-all
# Output harus menyertakan:
# services: ... http https ...
# atau
# ports: 80/tcp 443/tcp 443/udp ...
Membuka Port Admin API (Opsional, Hati-hati) #
Jika kamu perlu mengakses Admin API dari IP tertentu di jaringan internal:
# JANGAN buka Admin API ke internet publik
# Hanya buka ke network internal yang terpercaya
# Izinkan akses port 2019 hanya dari IP spesifik
sudo firewall-cmd --permanent --add-rich-rule='
rule family="ipv4"
source address="10.0.0.0/8"
port port="2019" protocol="tcp"
accept'
sudo firewall-cmd --reload
Mengelola Caddy dengan Systemd #
Sama seperti di Ubuntu, instalasi via package manager membuat systemd unit secara otomatis.
# Start dan enable Caddy
sudo systemctl start caddy
sudo systemctl enable caddy
# Cek status dengan output detail
sudo systemctl status caddy -l
# Reload konfigurasi tanpa downtime
sudo systemctl reload caddy
# Lihat log real-time
sudo journalctl -u caddy -f
# Log dengan priority warning ke atas
sudo journalctl -u caddy -p warning -n 50
Struktur File di RHEL/CentOS #
/usr/bin/caddy ← Binary Caddy
/etc/caddy/ ← Direktori konfigurasi
└── Caddyfile ← File konfigurasi utama
/var/lib/caddy/ ← Data Caddy
└── .local/share/caddy/ ← Sertifikat TLS
/var/log/caddy/ ← Log files
/usr/lib/systemd/system/
└── caddy.service ← Unit file systemd
(di RHEL path-nya /usr/lib/, bukan /lib/ seperti di Ubuntu)
Konfigurasi Awal dan Validasi #
# Edit Caddyfile
sudo nano /etc/caddy/Caddyfile
# Contoh konfigurasi minimal
cat << 'EOF' | sudo tee /etc/caddy/Caddyfile
{
email [email protected]
}
example.com {
reverse_proxy localhost:3000
}
EOF
# Validasi sebelum reload
caddy validate --config /etc/caddy/Caddyfile
# Reload jika valid
sudo systemctl reload caddy
# Cek log untuk error ACME atau masalah lain
sudo journalctl -u caddy -f
Troubleshooting Masalah Umum di RHEL/CentOS #
SELinux Memblokir Koneksi Jaringan #
# Gejala: reverse_proxy gagal connect ke backend
# Log: "dial tcp: connect: permission denied"
# Diagnosa
sudo ausearch -m avc -ts recent | grep caddy
# Solusi
sudo setsebool -P httpd_can_network_connect 1
sudo setsebool -P httpd_can_network_relay 1
SELinux Memblokir Baca File #
# Gejala: file_server mengembalikan 403 meski file ada
# Log: "open /path/to/file: permission denied"
# Diagnosa — cek context file
ls -lZ /path/to/webroot
# Solusi
sudo chcon -Rt httpd_sys_content_t /path/to/webroot
Firewall Memblokir Port #
# Gejala: Browser tidak bisa reach server, tapi Caddy berjalan
# Test dari server
curl -I localhost:80
# Test dari luar (jika ada akses ke server lain)
curl -I http://server-ip:80
# Cek status firewalld
sudo firewall-cmd --zone=public --list-all
# Buka port jika belum terbuka
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Caddy Gagal Start Setelah Install #
# Lihat error lengkap
sudo journalctl -u caddy -n 50 --no-pager
# Cek apakah ada proses lain di port 80/443
sudo ss -tlnp | grep ':80\|:443'
# Validasi Caddyfile
caddy validate --config /etc/caddy/Caddyfile
Checklist Deployment di RHEL/CentOS #
Gunakan checklist ini untuk memastikan semua sudah dikonfigurasi dengan benar:
INSTALASI
□ dnf copr enable @caddy/caddy berhasil
□ dnf install caddy berhasil
□ caddy version menampilkan versi yang benar
SELinux
□ getenforce menampilkan "Enforcing" (bukan Disabled)
□ httpd_can_network_connect diset ke "on"
□ httpd_can_network_relay diset ke "on"
□ File context webroot sudah httpd_sys_content_t
FIREWALL
□ firewall-cmd --zone=public --list-all menyertakan "http" dan "https"
□ Port 443/udp terbuka jika HTTP/3 diinginkan
□ firewall-cmd --reload sudah dijalankan
DNS
□ Domain mengarah ke IP server ini
□ dig +short domain.com mengembalikan IP server
SYSTEMD
□ caddy.service aktif (running)
□ caddy.service enabled (start on boot)
□ Caddyfile valid (caddy validate berhasil)
VERIFIKASI
□ https://domain.com bisa diakses dari browser
□ Sertifikat SSL valid (bukan warning)
□ Log tidak menampilkan error
Ringkasan #
- Gunakan COPR repository resmi untuk instalasi di semua distribusi berbasis RPM.
- SELinux harus dikonfigurasi, bukan dinonaktifkan — gunakan
setsebool -P httpd_can_network_connect 1danhttpd_can_network_relay 1.- Untuk troubleshooting SELinux, gunakan
ausearch -m avc | audit2whyuntuk memahami apa yang diblokir dan mengapa.- Firewalld perlu dikonfigurasi eksplisit — port 80 dan 443 tidak terbuka secara default di zone public.
- Selalu gunakan flag
--permanentdi firewall-cmd diikuti--reloadagar perubahan bertahan setelah reboot.- Gunakan
caddy validatesebelum setiap reload untuk mencegah konfigurasi rusak.- Checklist deployment di atas bisa digunakan sebagai runbook untuk setiap deployment baru.