Claude ile RHEL Sunucularımı Konuşarak Yönetiyorum: RHEL MCP Gateway

Claude ile RHEL Sunucularımı Konuşarak Yönetiyorum: RHEL MCP Gateway

Birden fazla Linux sunucusu yönetiyorsanız günün büyük kısmı hep aynı komutlarla geçer: systemctl status, journalctl, dnf check-update, df -h… Sunucuları zaten Cockpit ile web arayüzünden yönetiyordum. Bir gün şunu düşündüm: Cockpit zaten her sunucuda çalışıyor, yetkileri ve oturumları zaten yönetiyor. Bir yapay zekâ asistanı da Cockpit üzerinden bu sunuculara erişebilirse, “dünden beri çöken servis var mı?” diye sormam yetmez mi?

Bu fikirden RHEL MCP Gateway çıktı. Açık kaynaklı, GPL v3 lisanslı küçük bir servis. Sunucularımı Model Context Protocol (MCP) üzerinden Claude gibi yapay zekâ istemcilerine açıyor.

Nasıl çalışıyor?

Gateway bir Docker konteynerinde çalışıyor. Claude’a “Sunucu listesi”, “servis durumu”, “logları oku” gibi araçlar sunuyor. Claude bir aracı çağırınca gateway ilgili sunucunun Cockpit’ine bağlanıyor, komutu çalıştırıp sonucu yapılandırılmış JSON olarak döndürüyor.

Sunucularda ek bir ajan ya da eklenti yok. Cockpit’in kendi WebSocket protokolünü kullanıyorum: giriş yap, bir stream kanalı aç, komutu çalıştır, çıktıyı al. Yönetici gerektiren işlemler Cockpit’in kendi yetki yükseltmesiyle (superuser) yapılıyor.

Neler yapabiliyor?

Okuma araçları (onay gerektirmez):

  • Tüm sunucuların sağlık özeti: yük, çökmüş servisler, disk doluluğu
  • Sunucu bilgisi, kaynak kullanımı, en çok kaynak tüketen süreçler
  • Servis durumu, journalctl logları (zaman, öncelik ve arama filtresiyle)
  • Ağ bilgisi, firewalld kuralları, SELinux durumu
  • Bekleyen (güvenlik) güncellemeleri, paket bilgisi

Değiştiren araçlar:

  • Servis başlat/durdur/yeniden başlat
  • Güncelleme kur, paket kur/kaldır
  • Güvenlik duvarı kuralı ekle/kaldır
  • Yeniden başlat, serbest komut çalıştır

Değiştiren araçlarda bir güvenlik kuralı var: confirm: true verilmeden hiçbir şey yapılmıyor, yalnızca ne yapılacağı gösteriliyor. Böylece Claude önce planını söylüyor, ben onaylayınca çalıştırıyor. Girdiler (servis adı, paket adı, port) doğrulanıyor ve komutlar argv olarak verildiği için komut enjeksiyonu mümkün değil.

Pratikte şöyle konuşuyorum:

Ben: Sunuculardan herhangi birinde sorun var mı? Claude: (fleet_health çağırır) Bir sunucuda yük ortalaması 5.6, çekirdek sayısına göre yüksek. En çok CPU kullanan süreçlere bakayım mı?

Giriş: Ayrı kullanıcı veritabanı yok, Cockpit var

İlk sürümde Google ile giriş vardı ama anlamsızdı: zaten bir kimlik doğrulama sistemim (Cockpit) varken neden bir tane daha? Şimdi gateway’e giriş Cockpit hesabıyla yapılıyor. Kullanıcı adı ve parola, gateway’in çalıştığı makinedeki Cockpit’e doğrulatılıyor.

Claude tarafında standart MCP OAuth 2.1 akışı var. Connector eklediğinizde tarayıcıda bir giriş sayfası açılıyor, giriş yapınca Claude bir token alıyor. Dinamik istemci kaydı, PKCE, refresh token yenileme ve iptal desteği de var.

Bir de ikinci parola ekledim. Sunucu parolaları her zaman yeterince güçlü olmayabiliyor ve bu servis internete açık. Bu yüzden Cockpit girişine ek olarak .env dosyasında tanımlı uzun, rastgele bir gateway parolası isteniyor. Bu parola MCP adresine ?token= olarak eklenirse giriş sayfası onu ayrıca sormuyor. Parola tek başına giriş sağlamıyor; yanlışsa Cockpit parolası Cockpit’e hiç gönderilmiyor.

Bağlantı: Önce doğrudan, olmazsa tünel, en son SSH

Bu projenin en çok uğraştıran kısmı, her sunucunun ağ durumunun farklı olması oldu. Bazılarında Cockpit portu (9090) dışarıya açık, bazılarında güvenlik duvarı kapatıyor. Sonunda şu sıraya karar verdim:

  1. Cockpit’e doğrudan bağlan.
  2. Olmazsa SSH tüneli: sunucuya SSH ile bağlan ve bağlantının içinden sunucunun kendi localhost:9090 adresine tünel aç. Komutlar yine Cockpit üzerinden çalışıyor ama 9090’ı dışarıya açmak gerekmiyor.
  3. O da olmazsa düz SSH: yönetici komutları sudo -n ile çalışıyor.

Doğrudan Cockpit’e ulaşılamadığı 10 dakika boyunca hatırlanıyor, böylece her çağrıda zaman aşımı beklenmiyor. Her araç çıktısında bağlantının hangi yolla kurulduğu yazıyor (cockpit, cockpit-ssh, ssh); bir sorun olduğunda nedenini hemen görebiliyorum.

SSH tarafında birden çok kullanıcı deneniyor: bazı sunucular root ile, bazıları kendi kullanıcım ile giriş istiyor. Web panelinden ortak SSH anahtarı üretip bunu tüm sunucularda kullanabiliyorum; açık anahtarı authorized_keys dosyasına eklemek yetiyor.

Proxy ve sabit çıkış IP’si

Uzaktaki bazı sunucularda güvenlik duvarına hangi IP’yi ekleyeceğimi bilmem gerekiyordu. Panel artık gateway’in dış IP adresini gösteriyor. Daha da iyisi, sunuculara giden bağlantılar bir proxy üzerinden geçebiliyor (HTTP CONNECT veya SOCKS5). Böylece tüm sunucular tek bir sabit adres görüyor. Proxy hem genel olarak hem de sunucu bazında ayarlanabiliyor; ek kütüphane kullanmadan Python’un standart kütüphanesiyle yazıldı.

Web paneli

Sunucuları eklediğim basit bir panel var:

  • Cockpit kullanıcısı/parolası (şifreli saklanıyor), SSH ayarları, proxy
  • Kaydetmeden önce bağlantı testi: bilgiler gerçekten çalışıyor mu diye sunucuya bağlanılıyor. Bağlanılamazsa kayıt yapılmıyor.
  • Test et butonu ve durum göstergesi: ✓ Cockpit çalışıyor (doğrudan ya da tünelle), ⚠ yalnızca SSH çalışıyor, ✗ bağlanılamıyor

Kurulum

git clone https://github.com/bmericc/rhel-mcp-gateway
cd rhel-mcp-gateway
cp sample.env .env      # SECRET_KEY, PUBLIC_URL, MCP_API_KEY, ALLOWED_USERS...
docker compose up -d --build

Önüne HTTPS sonlandıran bir reverse proxy (nginx, Caddy) koymanız gerekiyor. Ardından Claude’da Settings → Connectors → Add custom connector bölümüne https://<adresiniz>/sse?token=<gateway parolası> adresini girip Cockpit hesabınızla giriş yapmanız yeterli. Claude Code için:

claude mcp add --transport sse rhel-gateway "https://<adresiniz>/sse?token=<token>"

Testler

Projede 200’den fazla test var. Cockpit için gerçek cockpit-ws davranışına göre yazılmış sahte bir sunucu kullanıyorum, SSH taklit ediliyor. Kritik akışları (OAuth, tünel, proxy) ayrıca gerçek cockpit-ws ve sshd ile de denedim. GitHub Actions her değişiklikte testleri çalıştırıyor.

Sırada ne var?

  • Paket ve güvenlik duvarı araçları şu an RHEL ailesine (dnf, firewalld) özel. Debian/Ubuntu sunucular için apt ve ufw desteği eklemeyi düşünüyorum.
  • Sunucu anahtarı doğrulaması (known_hosts) ve daha sıkı TLS ayarları.

Kod GitHub’da: github.com/bmericc/rhel-mcp-gateway. Deneyen olursa geri bildirimlerinizi bekliyorum.

Son güncelleme 7 Ekim 2026