Warning LC_CTYPE Tiap Login SSH Itu Ulah Laptop Sendiri
Setiap login SSH ke VPS muncul setlocale: LC_CTYPE cannot change locale. Ternyata pengirimnya laptop Debian sendiri lewat default SendEnv.
Dua Baris Setlocale di Bawah Banner Login
Tadi pagi saya SSH pertama kali ke VPS baru. Banner MOTD muncul, uptime rapi, welcome text dari provider. Terus persis di bawahnya, dua baris yang nggak diundang:
setlocale: LC_CTYPE cannot change locale
setlocale: LC_CTYPE cannot change locale
Dan itu muncul lagi tiap buka shell baru. Refleks pertama saya: locale servernya rusak. Saya jalankan locale di server, hasilnya LANG=C.UTF-8 plus deretan LC_* kosong. locale -a cuma nampilin C, C.UTF-8, dan POSIX. Jadi locale yang dicari emang nggak ada di server.
Niat pertama saya gener ulang locale pakai locale-gen. Untung ditahan dulu. Image minimal emang sengaja dikit locale-nya, by design, bukan kerusakan. Server nggak minta apa-apa. Yang cerewet justru laptop Debian saya sendiri: setiap konek, client SSH saya ngirim LANG dan semua variabel LC_* ke server, dan shell di server berusaha nurut.
SendEnv Itu Akumulatif, Bukan First-Value-Wins
Client SSH bawaan Debian punya default ini di /etc/ssh/ssh_config [2]:
SendEnv LANG LC_*
Artinya tiap koneksi, laptop mengirim LANG plus semua variabel yang cocok pola LC_*. Server Debian kebanyakan juga punya AcceptEnv LANG LC_* di sshd_config [3], jadi variabelnya diterusin ke shell saya. Shell manggil setlocale, libc di server nggak kenal locale itu, keluarlah dua baris tadi. Tanpa AcceptEnv yang cocok, variabel yang dikirim dibuang diam-diam, dan default sshd memang nggak menerima variabel env apa pun [3].
Saya udah coba matikan dari ~/.ssh/config, tapi tetap terkirim. Di sinilah salah paham saya. Urutan baca config: opsi command-line, lalu ~/.ssh/config, lalu /etc/ssh/ssh_config beserta file /etc/ssh/ssh_config.d/*.conf yang di-include di awalnya [1][2]. Buat direktif biasa berlaku first-obtained-value-wins: nilai pertama yang didapat menang, makanya deklarasi spesifik ditaruh di atas. Saya kira SendEnv juga begini.
Nggak. SendEnv itu akumulatif: tiap kemunculan nambah nama variabel ke daftar yang sama, bukan nimpa. Namanya boleh wildcard, dan prefix - menghapus entri dari daftar [1]. Logika "blok bawah nggak menang" nggak berlaku di sini. Interaksi negasi antar file agak halus soal urutan baca, jadi daripada debat teori, saya verifikasi hasil akhirnya langsung.
Rapikan di Pengirim, Cek Pakai ssh -G
Di ~/.ssh/config:
Host vps-baru
HostName 203.0.113.10
SendEnv -LANG -LC_*
Kalo masih mau kirim variabel yang aman buat server mana pun, tambahin baris kedua: SendEnv COLORTERM NO_COLOR. Dua-duanya nggak bikin setlocale di server eror.
Cek config efektif tanpa perlu konek:
ssh -G vps-baru | grep -i sendenv
ssh -G nge-dump semua opsi yang bakal dipakai buat host itu, setelah semua file config digabung. Kalo sendenv LANG LC_* masih muncul di output, berarti entri system config masih nyangkut di daftar. Opsi paling malas yang pasti jalan di laptop pribadi: beri komentar satu baris SendEnv LANG LC_* di /etc/ssh/ssh_config. Laptop sendiri, nggak ada yang protes.
Login lagi: banner bersih, dua baris warning hilang. Catatan kecil: TERM tetap terkirim kalo ada pty, itu bagian protokol SSH, nggak bisa dan emang nggak perlu diblokir [1].
Kapan locale-gen di Server Tetap Masuk Akal
Kalo server emang butuh locale itu, bukan cuma buat menyenangkan laptop pengirim, baru generate di sisi server: buka komentar baris yang sesuai di /etc/locale.gen, lalu jalankan locale-gen atau dpkg-reconfigure locales [4]. Contoh kasus yang masuk akal: aplikasi di server bergantung ke collation bahasa tertentu, ada cron yang outputnya format tanggal lokal, atau ada user lain di mesin itu yang butuh. Wiki Debian aja menyarankan default locale None buat host yang diakses via SSH [4].
Pendapat saya tegas: image minimal dirancang ramping, jangan dipaksa generate locale cuma supaya warning di laptop hilang. Variabel yang dikirim tanpa izin ya ditarik dari pengirimnya, bukan servernya yang dibebani. Sekaligus jadi pelajaran: SendEnv nggak ikut aturan first-value-wins, dan ssh -G itu cara paling murah buat berhenti menebak.
Sumber
- OpenBSD, ssh_config(5) [1]
- Debian Manpages, ssh_config(5) [2]
- OpenBSD, sshd_config(5) [3]
- Debian Wiki, Locale [4]
[1] https://man.openbsd.org/ssh_config [2] https://manpages.debian.org/bookworm/openssh-client/ssh_config.5.en.html [3] https://man.openbsd.org/sshd_config [4] https://wiki.debian.org/Locale