SSD Nodes Learn 🎉 VPS $5.50/महिन्यापासून
मार्गदर्शक Matt Connorद्वारे Matt Connor · अपडेटेड 2026-08-13

sysadmins साठी Claude: Linux server कामे आणि सुरक्षितता

failed unit चे logs वाचणे, systemd unit तयार करणे, nginx आणि Compose files तपासणे यासाठी Claude वापरा. कोणती माहिती कधीही paste करू नये ते जाणून घ्या.

sysadmins साठी Claude: आधी सल्ला, नंतर अंमलबजावणी

sysadmins साठी Claude हे reviewer म्हणून सर्वाधिक उपयुक्त ठरते. तुम्ही log excerpt, config file, ओळखू न येणारी command किंवा error string दिल्यावर, सर्व्हरवर काहीही बदलण्यापूर्वी तपासता येईल असे स्पष्टीकरण तुम्हाला मिळते. चुकीच्या उत्तरामुळे तुम्ही ती command चालवेपर्यंत कोणतीही हानी होत नाही. त्यामुळे model ला त्या मर्यादेपर्यंत, म्हणजे सल्ला देण्यापुरतेच ठेवणे, हीच संपूर्ण सुरक्षा पद्धत आहे.

भाड्याने घेतलेल्या Linux VPS (virtual private server) वर दर आठवड्याला सहा प्रकारची कामे येतात. खालील प्रत्येक कामासाठी उपयुक्त prompt pattern, उत्तराची खात्री करणारी command आणि अपेक्षित failure mode दिला आहे. यापैकी कोणत्याही कामासाठी model ला तुमच्या सर्व्हरचा access आवश्यक नाही.

Production box वर काम करताना क्रम महत्त्वाचा आहे: प्रथम स्पष्टीकरण वाचा, नंतर स्वतः तपासणी करा आणि त्यानंतर निर्णय घ्या. Scratch VM वर autonomy स्वीकारता येते. तुमच्या ग्राहकांना सेवा देणाऱ्या box वर review अधिक महत्त्वाचे ठरते, कारण model ज्या स्थितीचा अंदाज लावत आहे ती प्रत्यक्ष स्थिती त्याला दिसत नाही.

तुम्ही कधीही पेस्ट करू नये अशा गोष्टी

प्रॉम्प्टमधील प्रत्येक गोष्ट तुमच्या सर्व्हरबाहेर जाते. खालील चार प्रकारच्या गोष्टी सर्व्हरवरच ठेवा:

  • Private keys: ~/.ssh/id_ed25519, /etc/ssh/ssh_host_*_key आणि /etc/letsencrypt/live/ अंतर्गत असलेली कोणतीही TLS (transport layer security) key.
  • Credential files: .env, ~/.aws/credentials, /root/.docker/config.json आणि कोणत्याही file किंवा log line मधील database passwords.
  • Account data: /etc/shadow आणि /etc/gshadow. कोणत्याही sysadmin प्रश्नाचे उत्तर देण्यासाठी password hash आवश्यक नसतो.
  • तुमच्या users शी संबंधित कोणतीही माहिती: email addresses, order rows, session cookies किंवा PII (personally identifiable information) असलेले request logs.

Public keys पेस्ट करणे सुरक्षित आहे. Private keys सुरक्षित नाहीत. दोन्ही files पहिल्या दृष्टीक्षेपात सारख्या दिसू शकतात. त्यामुळे copy करण्यापूर्वी पहिली ओळ वाचा: ज्या file च्या पहिल्या ओळीत BEGIN OPENSSH PRIVATE KEY असते, ती prompt मध्ये कधीही टाकू नका. तुमचे SSH key material व्यवस्थित वेगळे ठेवणे यासाठी स्वतंत्रपणे दहा मिनिटे देणे योग्य आहे.

पेस्ट करण्यापूर्वी redact करा. 200 lines मध्ये एखादा token स्वतः ओळखण्यावर अवलंबून राहू नका:

sudo journalctl -u myapp -n 200 --no-pager | sed -E 's/(token|secret|password|api[_-]?key)[=:][^[:space:]]+/\1=REDACTED/gI'

Docker मध्ये एक विशिष्ट सापळा आहे. docker compose config तुम्ही दिलेली .env values त्याने print केलेल्या output मध्ये interpolate करते. त्यामुळे disk वरील file मध्ये secret नसला, तरी तो output secret असतो. docker compose config -q वापरा. ते validation करते आणि काहीही print करत नाही. Agent ला काय पाहण्याची परवानगी असावी यासंबंधीच्या व्यापक धोरणासाठी, AI agents पासून secrets दूर ठेवणे environment स्तरावरील बाबी स्पष्ट करते.

काम 1: ही सेवा का अयशस्वी झाली?

उत्तर असलेल्या दोन commands पासून सुरुवात करा:

systemctl status myapp.service --no-pager
sudo journalctl -u myapp.service -b -n 100 --no-pager -o short-iso

दोन्ही commands सोबत model ला अंदाज लावता येणार नाही असा संदर्भ द्या: distribution आणि version, शेवटचा बदल काय केला, सेवा यापूर्वी कधी चालली होती का, आणि ती किती वेळापूर्वी बंद पडली. आधी mechanism विचारा.

Ubuntu 24.04. myapp.service मध्ये unit संपादित करेपर्यंत व्यवस्थित चालू होते. ते एक तासापूर्वी केले. येथे systemctl status आणि journal मधील शेवटच्या 100 lines आहेत. पहिली वास्तविक error कोणती आहे आणि तिचा अर्थ काय? अजून fix सांगू नका.

या prompt मधील "अजून fix सांगू नका" याचा प्रत्यक्ष उपयोग होतो. Retries मुळे निर्माण झालेल्या messages खाली logs मध्ये पहिली failure लपते. Model ला fix विचारल्यास ते दिसलेल्या शेवटच्या line चे स्पष्टीकरण देऊ शकते. महत्त्वाची line बहुतेक वेळा या noise च्या सुमारे वीस lines आधी असते.

यातून Main PID: 1841 (code=exited, status=203/EXEC) सारखी line मिळू शकते. Exit status 203/EXEC याचा अर्थ kernel ExecStart मध्ये नमूद केलेली file execute करू शकला नाही. याची दोन सामान्य कारणे आहेत: path अस्तित्वात नाही किंवा file अस्तित्वात असूनही executable नाही. Installed नसलेल्या interpreter चे नाव असलेली #! line देखील हाच status निर्माण करते. हे सर्व ls -l आणि head -1 वापरून तपासता येते.

Failure mode: बनवलेले कारण. खूप कमी मजकूर paste केल्यास model उणीव भरून काढते आणि "port आधीच वापरात आहे" यासारखे generic कारण सांगते. उपाय म्हणून पुन्हा एक प्रश्न विचारा: "मी दिलेल्या मजकुरातील कोणती line याला समर्थन देते?" मजकुरात दाखवता न येणारे कारण हा अंदाज असतो.

काम 2: systemd unit किंवा cron entry तयार करा

Unit file साठी आवश्यक तथ्ये द्या: अचूक command, तो कोणत्या user म्हणून चालेल, working directory, network साठी प्रतीक्षा करणे आवश्यक आहे का, आणि तो non-zero exit झाल्यावर काय झाले पाहिजे. त्यानंतर काही enable करण्यापूर्वी मिळणारा output पडताळा.

sudo systemd-analyze verify /etc/systemd/system/myapp.service
sudo systemctl daemon-reload
sudo systemctl start myapp.service
systemctl status myapp.service --no-pager

systemd-analyze verify ही file systemd ज्या पद्धतीने parse करते त्याच पद्धतीने parse करते. त्यामुळे मानवी नजरेतून सुटणाऱ्या चुका ती शोधते. चुकीचे लिहिलेले directive असल्यास /etc/systemd/system/myapp.service:7: Unknown key name 'Enviroment' in section 'Service', ignoring. दिसते. Binary उपलब्ध नसल्यास Command /usr/local/bin/myapp is not executable: No such file or directory दिसते. daemon-reload दरम्यान दोन्ही त्रुटी दिसत नाहीत. म्हणून unit व्यवस्थित load होऊ शकते आणि चालवण्याच्या क्षणी अपयशी ठरू शकते.

दोन drafting चुका वारंवार आढळतात. पहिली म्हणजे After=network.target. याचा अर्थ फक्त network stack configure झाला आहे; address उपलब्ध आहे असा त्याचा अर्थ नाही. एखादी service विशिष्ट IP वर bind करत असल्यास boot वेळी bind: Cannot assign requested address मुळे ती अपयशी ठरते. यासाठी Wants=network-online.target आणि After=network-online.target वापरा. दुसरी चूक म्हणजे daemonise होणाऱ्या program साठी Type=simple वापरणे. systemd पहिल्या process ला service मानते. parent process लगेच exit होतो आणि unit dead म्हणून mark केली जाते, पण प्रत्यक्ष process systemd च्या व्यवस्थापनाबाहेर चालू राहतो.

Schedule वाचण्याऐवजी त्याची पडताळणी करा:

systemd-analyze calendar 'Mon *-*-* 04:00:00'

यामुळे normalised form आणि expression पुढील वेळी कधी चालेल ते दिसते. त्यामुळे expression चा अर्थ काय यावरील वाद संपतो. Timer आणि crontab यांपैकी निवड करत असल्यास, VPS वरील systemd services आणि timers यामध्ये या दोन्हींची तुलना दिली आहे.

तुम्ही विचारल्याशिवाय कोणतेही model सांगणार नाही असा Cron मधील एक महत्त्वाचा trap आहे. Cron jobs minimal environment मध्ये चालवतो. त्यामुळे PATH साधारणपणे /usr/bin:/bin असते आणि तुमचा shell profile कधीही read केला जात नाही. Terminal मध्ये paste केल्यावर चालणारे job cron अंतर्गत /bin/sh: 1: docker: not found मुळे अपयशी ठरते, कारण ते binary /usr/local/bin मध्ये आहे. Crontab मध्ये absolute paths वापरा.

कार्य 3: live करण्यापूर्वी nginx किंवा Compose फाइलचे पुनरावलोकन करा

या कार्यातून सर्वाधिक फायदा होतो. फाइल पेस्ट करा, ती काय करणार आहे ते सांगा आणि प्रत्यक्षात ती काय करते याचे ओळीनुसार स्पष्टीकरण मागा.

हा vhost example.com HTTPS वर उपलब्ध करून देईल आणि /api ला port 8080 वरील स्थानिक सेवेकडे proxy करेल. ते मला पुन्हा वाचून दाखवा आणि या वर्णनाशी जुळत नसलेली कोणतीही गोष्ट नमूद करा.

त्यानंतर grammar तपासणारे tool चालवा:

sudo nginx -t
docker compose config -q

nginx -t हे nginx: configuration file /etc/nginx/nginx.conf test is successful छापते किंवा nginx: [emerg] unknown directive "proxy_pas" in /etc/nginx/conf.d/app.conf:12 प्रमाणे फाइलचे नाव आणि ओळ क्रमांक दाखवते. फाइलचे parsing यशस्वी झाल्यास docker compose config -q काहीही छापत नाही. Indentation चुकल्यास yaml: line 7: did not find expected key सारखा स्पष्ट error दाखवते.

यापैकी कोणतेही tool configuration चा हेतू तपासत नाही. nginx -t पास होणारी configuration देखील चुकीच्या port कडे proxy करू शकते किंवा तुम्हाला 127.0.0.1 अपेक्षित असताना 0.0.0.0 वर listen करू शकते. याच फरकामुळे model उपयुक्त ठरते आणि याच ठिकाणी ते अपयशीही ठरते: एखादा directive दुरुस्त करण्यास सांगितल्यावर ते अनेकदा संपूर्ण फाइल पुन्हा लिहिते आणि तुमचे दोन directive शांतपणे काढून टाकते. बदललेल्या ओळी आणि प्रत्येक बदलाचे कारण मागा. त्यानंतर स्वतः हाताने संपादन करा.

प्रत्यक्षात कोणते ports सार्वजनिकरीत्या उपलब्ध केले आहेत ते पडताळा:

sudo ss -tulpn

sudo शिवाय listening sockets दिसतात, पण ते कोणत्या processes च्या मालकीचे आहेत हे दिसत नाही. त्या output मध्ये अनपेक्षित गोष्ट आढळल्यास, ports म्हणजे काय आणि Linux त्यांना कसे bind करते हा अधिक संक्षिप्त लेख वाचा.

काम 4: अपरिचित command चालवण्यापूर्वी त्याचे स्पष्टीकरण घ्या

command paste करा आणि त्याबद्दल चार प्रश्न विचारा: प्रत्येक flag काय करते, ते काय लिहिते, ते काय delete करते आणि ते दोनदा चालवल्यास काय होते. शेवटचा प्रश्न इतर प्रश्नांपेक्षा जास्त नुकसान टाळतो.

find /var/log -name '*.gz' -mtime +7 -delete विचारात घ्या. चांगले उत्तर सांगते की -mtime +7 पूर्ण 24 तासांचे कालखंड मोजते आणि अपूर्ण भाग टाकून देते. त्यामुळे ते सात दिवस जुन्या नसून किमान आठ दिवस जुन्या files शी जुळते. तसेच ते सांगते की find त्याच्या expression चे मूल्यमापन डावीकडून उजवीकडे करते. त्यामुळे -delete ला -name च्या आधी हलवल्यास सुरुवातीच्या path अंतर्गत असलेले सर्व काही delete होते. हा दुसरा मुद्दा find man page मध्ये warning म्हणून दिला आहे आणि त्यामुळे लोकांचे /var/log गमावले गेले आहेत.

किंवा rsync -a --delete /srv/app/ /backup/app/ विचारात घ्या. source वरील शेवटचा slash म्हणजे “या directory मधील contents”. तो काढल्यास /backup/app/app/ मिळते. --delete जोडल्यास source मध्ये नसलेली destination मधील प्रत्येक गोष्ट remove केली जाते. Mirror साठी हे योग्य आहे; पण source path चुकीचा असल्यास ही आपत्ती ठरते.

Model वर नाही, तर tool वापरून पडताळा:

rsync -a --delete --dry-run /srv/app/ /backup/app/ | head -20
find /var/log -name '*.gz' -mtime +7

find हे -delete शिवाय चालवा. त्यामुळे नुकसान होण्याऐवजी list मिळते.

अपयशाचा प्रकार: flag hallucination. तीस वर्षांची documentation असलेल्या tools बाबत model विश्वसनीय असते. पण vendor CLIs (command line interfaces) आणि अलीकडील subcommands बाबत ते कमी विश्वसनीय असते. अशा वेळी ते वाचायला योग्य वाटणारा, पण प्रत्यक्षात अस्तित्वात नसलेला flag तयार करू शकते. --help हे एका सेकंदात सत्य स्पष्ट करते. Quoting ही दुसरी कमकुवत बाजू आहे. त्यामुळे एखाद्या command मध्ये $(...) expression वापरले असल्यास स्पष्टीकरणावर विश्वास ठेवण्याऐवजी command चालण्यापूर्वी command substitution कसे expand होते ते वाचा.

Job 5: तुमच्या shell history चे runbook मध्ये रूपांतर करा

एखादी गोष्ट कार्यान्वित करण्यासाठी तुम्ही नुकतेच दोन तास खर्च केले. ते ज्ञान तुमच्या scrollback मध्ये आहे आणि पुढच्या महिन्यात ते नाहीसे होईल.

history 200 > /tmp/session.txt

ती फाइल वाचा आणि ती कुठेही वापरण्यापूर्वी password, token किंवा customer identifier असलेली प्रत्येक ओळ हटवा. Linux box वर secret शोधण्यासाठी shell history हे सर्वात विश्वासार्ह ठिकाणांपैकी एक आहे, कारण प्रत्येकजण किमान एकदा तरी असे काहीतरी inline टाइप करतो. तुमच्या ~/.bashrc मध्ये HISTCONTROL=ignorespace सेट करा. त्यानंतर सुरुवातीला space असलेली command history मध्ये अजिबात लिहिली जाणार नाही.

उपयोगी runbook तयार करणारा prompt केवळ steps नव्हे, तर checks मागतो:

ही shell session एका fresh Debian 13 box वर working Postgres install करण्यासाठी वापरली गेली. ती numbered runbook म्हणून लिहा. प्रत्येक step मध्ये एकच command द्या. प्रत्येक step नंतर ते यशस्वी झाल्याचे सिद्ध करणारी command द्या आणि healthy output कसा दिसतो ते स्पष्ट करा. माझ्या specific host वर अवलंबून असलेला प्रत्येक step चिन्हांकित करा.

अपयशाचा प्रकार: नीटनेटकी कथा. काही दुरुस्ती करण्यापूर्वी तुम्ही एखादा step दोनदा चुकीचा केला होता. Transcript मध्ये तो step नसल्यास मजकूर अधिक स्वच्छ दिसतो, म्हणून model तो step गुळगुळीत करून काढून टाकतो. Runbook ची तुमच्या history शी तुलना करा आणि ती दुरुस्ती पुन्हा समाविष्ट करा. तसेच तो plausible verification commands तयार करतो. त्यामुळे फाइल save करण्यापूर्वी त्याने लिहिलेली प्रत्येक check प्रत्यक्ष चालवून पाहा. Runbook मध्ये first boot समाविष्ट असल्यास, नवीन VPS वरील पहिल्या दहा मिनिटांशी त्याची तुलना करा, जेणेकरून आधीच सोडवलेल्या समस्येची आणखी खराब आवृत्ती तुम्ही लिहिणार नाही.

कार्य 6: त्रुटी संदेशाचे उपायात रूपांतर करा

अचूक string, ती निर्माण करणारी command आणि ती दिसण्यापूर्वी तुम्ही केलेला एकमेव बदल द्या. प्रत्येक संभाव्य कारणासाठी ते ओळखणारी command देऊन, संभाव्य कारणांना क्रमवारीत मांडण्यास सांगा. त्यामुळे उत्तराची पडताळणी करता येते.

nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use). संभाव्य कारणांना क्रमवारीत मांडा आणि प्रत्येक कारणाची पुष्टी किंवा ते बाद करण्यासाठी एक command द्या.

या त्रुटीमागील mechanism संदिग्ध नाही: दुसरी process port 80 आधीच वापरत आहे आणि sudo ss -tulpn | grep ':80 ' तिचे नाव दाखवते. अनेकदा failed reload नंतर दुसरा nginx master process सुरूच राहतो. किंवा Apache dependency म्हणून समाविष्ट होऊन त्याच्या package मुळे सुरू होतो.

अपयशाचा प्रकार: कारण लपवून काम करणारा उपाय. chmod 777, --privileged, SELinux अक्षम करणे आणि service root म्हणून चालवणे यांमुळे त्रुटी दिसेनाशी होते. अरुंद permission का अपयशी ठरली हे model ने स्पष्ट करेपर्यंत permissions अधिक व्यापक करणारा कोणताही उपाय स्वीकारू नका. ते स्पष्टीकरण हेच खरे उत्तर आहे. Workaround मुळे फक्त त्रुटी शांत होते.

यामध्ये नियमितपणे कोणत्या चुका होतात

  • ते तुमचा सर्व्हर पाहू शकत नाही. प्रत्येक उत्तर तुम्ही दिलेल्या मजकुरावर आधारित असते आणि दिलेला उतारा अपुरा आहे हे ते सांगणार नाही.
  • आवृत्त्यांबाबत त्याची अचूकता ढासळते. विविध distributions आणि releases मध्ये package names आणि default flags बदलतात; model त्या सर्वांचा सरासरी अंदाज लावतो.
  • चूक असतानाही ते प्रवाहीपणे उत्तर देते. बनावट mechanism अगदी योग्य mechanism सारखाच वाटतो. म्हणूनच वर दिलेल्या प्रत्येक कारणासोबत त्याची चाचणी करणारी command दिली आहे.
  • दीर्घ sessions मध्ये ते संदर्भाचा धागा गमावते. दोन तासांच्या संभाषणाच्या सुरुवातीतील facts शेवटच्या उत्तरांवर परिणाम करणे थांबवतात.

शेवटची समस्या model पेक्षा काम करण्याच्या पद्धतीशी अधिक संबंधित आहे. दीर्घ Claude Code session मध्ये context व्यवस्थापित करणे हा तिचा व्यावहारिक उपाय आहे: लहान sessions वापरा आणि प्रत्येक session मध्ये एकच task ठेवा.

सर्व्हरवरच agent ठेवणे

वरील सर्व मजकूर copy आणि paste करण्यापुरताच आहे, त्यामुळे model तुमच्या मशीनला स्पर्श करत नाही. Agent box वर चालू होऊन files वाचू लागला आणि commands execute करू लागला की जोखमीचे स्वरूप बदलते: चुकीच्या command मुळे एखादी service बंद पडू शकते. root ऐवजी agent साठी स्वतंत्र unprivileged user द्या, त्याच्या कार्यपद्धतीची सवय होईपर्यंत तो production box पासून दूर ठेवा आणि आधी snapshot घ्या. VPS वर Claude Code सुरक्षितपणे चालवणे यात sandboxing आणि permission model समजावले आहे. tmux मध्ये Claude Code चालवणे जोखमीचा दुसरा भाग हाताळते, कारण SSH (secure shell) session तुटल्यास foreground agent कामाच्या मध्यातच बंद पडतो. हा account तुम्ही कोणत्याही service account प्रमाणे तयार करा. VPS वरील least privilege users मध्ये त्याची सविस्तर पद्धत दिली आहे.

FAQ

Claude माझे server logs थेट वाचू शकते का?

स्वतःहून नाही. Chat interface मध्ये तुम्ही paste केलेला मजकूरच दिसतो. Server वर command line tool म्हणून चालवलेले Claude Code, ते सुरू करणाऱ्या user च्या permissions नुसार files वाचू आणि commands चालवू शकते. हा अधिक मोठा trust decision आहे. सामान्य support प्रश्नासाठी agent ला shell access देण्यापेक्षा redacted केलेला 100 ओळींचा excerpt paste करणे अधिक जलद आणि सुरक्षित आहे.

Server मधून मी काय कधीही paste करू नये?

Private keys, .env files आणि इतर credential stores, /etc/shadow, तसेच तुमच्या users च्या मालकीचा कोणताही data paste करू नका. Log excerpts prompt पर्यंत पोहोचण्यापूर्वी त्यांमधील tokens redact करा. एक सहज लक्षात न येणारे उदाहरण म्हणजे docker compose config चे output. त्यात तुमची .env values interpolated केलेली असतात. त्यामुळे docker compose config -q वापरा. ते file validate करते आणि काहीही print करत नाही.

Claude ला production VPS वर commands चालवू देणे सुरक्षित आहे का?

त्याला कोणतीही पार्श्वभूमी नसलेला नवीन admin समजा: वाचण्यासाठी योग्य, पण लिहिण्यासाठी review आवश्यक. Production वर explanation मागा आणि command स्वतः चालवा. Agent कडून execution करून घ्यायचे असल्यास, त्याला blanket sudo नसलेले dedicated unprivileged account द्या. सुरुवात staging box वर करा, जिथे चुकीमुळे outage ऐवजी rebuild करावा लागेल.

Claude अस्तित्वात नसलेला flag का सुचवते?

कारण ते plausible text चे prediction करते आणि plausible flag वास्तविक flag सारखाच दिसतो. Vendor CLIs आणि नवीन subcommands मध्ये हे अधिक घडते. अशा ठिकाणी model मागील documentation अपुरी असू शकते किंवा ती नंतर बदललेली असू शकते. --help आणि man हे अंतिम प्रमाण मानावेत. Delete किंवा overwrite करणाऱ्या कोणत्याही command साठी प्रथम dry run करणे आवश्यक आहे.

Enable करण्यापूर्वी systemd unit कसे तपासावे?

sudo systemd-analyze verify /etc/systemd/system/myapp.service चालवा. ते systemd च्या स्वतःच्या parser ने file parse करते, unknown directives त्यांच्या line numbers सह दाखवते आणि missing किंवा executable नसलेले ExecStart binary flag करते. त्यानंतर daemon-reload आणि start चालवा आणि systemctl status वाचा. मगच ते enable करा, कारण cleanly load होणारे unit पहिल्यांदा चालवताना fail होऊ शकते.