Menggunakan SSH key di TPM

Trusted Platform Module (TPM) adalah teknologi kriptografi berbasis hardware. TPM digunakan untuk memastikan proses boot tidak dimodifikasi (secure boot), dan digunakan oleh sistem operasi untuk enkripsi (misalnya Bitlocker) dan menyimpan informasi user (Windows Hello).

Di dalam komputer, TPM ini bisa berupa sebuah chip, atau sudah ada di dalam CPU. Prosesor Intel sejak Skylake/Intel Gen 6, dan AMD (sejak AM4) sudah punya fitur TPM built in. Kita bisa menggunakan fitur TPM ini untuk key SSH.

Ketika berbicara tentang SSH, ada banyak implementasinya (misalnya dropbear, tinyssh, dsb), saya akan menggunakan spesifik OpenSSH di tulisan ini.OpenSSH ini tersedia di hampir semua platform, termasuk juga Windows.

Intinya di sini saya akan membahas bagaimana membuat SSH Key yang tidak bisa dicopy, dan kita cukup menggunakan PIN atau sidik jari untuk login SSH.

Login SSH dengan fingerprint/Windows Hello

Berbagai metode autentikasi OpenSSH

Secara umum SSH bisa melakukan autentikasi dengan password atau key. Secara detail, ada banyak sekali metode autentikasi yang didukung OpenSSH, misalnya:

  • dengan password
  • dengan public key
  • dengan hardware key berbasis FIDO (Fast ID Online V2.0 authentication)
  • dengan host based authentication
  • dengan kerberos/GSSAPI
  • dengan sertifikat (biasanya diatur dengan Public Key Infrastructure/PKI)
  • dengan hardware smart card berbasis PKCS#11 (ini pun banyak standardnya, misalnya PIV dan CAC).
  • dengan PAM (Pluggable Authentication Module)

Di tulisan ini saya tidak ingin membahas semuanya (bisa sangat panjang). Dengan PAM berbagai autentikasi bisa dilakukan, misalnya 2FA dengan Google authenticator bisa ditambahkan.

Pertama saya hanya ingin memperkenalkan pemakaian key SSH dibandingkan password. Setelah mengetahui pemakaian dan batasan key berbasis file, saya akan memperkenalkan penggunakan key menggunakan hardware TPM yang sudah ada di banyak komputer modern untuk autentikasi SSH.

Autentikasi SSH dengan Password

Ini pemakaian SSH paling dasar dan paling sederhana. Tapi untuk alasan keamanan, memakai SSH dengan password sangat tidak disarankan, alasannya:

  • password bisa dibruteforce dari eksternal (dari server manapun yang bisa mengakses port SSH server target)
  • password bisa disniff/log dengan keylogger (di komputer orang yang menjalankan SSH)
  • jika ada kebocoran sebuah sistem dan file password dicuri orang (misalnya /etc/shadow) password bisa dibruteforce dan dipakai untuk masuk ke sistem lain

Selain itu banyak orang memakai password yang lemah, atau memakai password yang sama di banyak tempat.

Autentikasi SSH dengan key

Dengan berbagai kekurangan password, untuk lebih amannya kita bisa memakai SSH Key. Atau tepatnya lagi autentikasi ini memakai key pair (pasangan private dan public key), tapi umumnya akan disebut sebagai “ssh key” saja.

SSH key ini paling dasar bentuknya adalah file yang berisi private key. Dari private key kita bisa menciptakan public key. Isi public key ini kemudian bisa disalin dengan copas ke mesin tujuan ~/.ssh/authorized_keys (atau dengan skrip ssh-copy-id).

Membuat keypair bisa dilakukan di operating system mana saja, tidak perlu hardware tambahan:

ssh-keygen

Dan defaultnya key berjenis RSA akan diciptakan di $HOME/.ssh/id_rsa dan public keynya di $HOME/.ssh/id_rsa.pub ada juga pertanyaan apakah key-nya ingin diberi password atau tidak. Ada banyak jenis key lain (tidak akan dijelaskan di sini), dan kita bisa membuat banyak key (disimpan dengan nama berbeda).

Jika file id_rsa.pub terhapus, kita bisa ciptakan lagi dari id_rsa tapi jika id_rsa yang terhapus maka tidak bisa diciptakan dari id_rsa.pub.

Setelah itu kita bisa menyalin id_rsa.pub ke host target, di beberapa sistem operasi skrip ssh-copy-id bisa digunakan seperti ini:

ssh-copy-id targethost

Nanti kita akan ditanya password untuk targethost, setelah itu jika semua sukses, berikutnya kita melakukan ssh targethost tidak butuh password lagi (kecuali private keynya diberi password, kita perlu memasukkan password untuk key-nya).

Jika skrip ssh-copy-id tidak tersedia (ini bukan bawaan distribusi resmi OpenSSH), maka kita bisa menambahkan isi $HOME/.ssh/id_rsa.pub (ingat .pub ya, bukan yang tanpa pub), ke $HOME/.ssh/authorized_keys di targethost. File authorized_keys ini bisa terdiri dari banyak baris (banyak key dari banyak host), jadi jangan asal timpa, tapi insert public key baru.

Perhatikan juga permission .ssh dan .ssh/authorized_keys. Jika tidak yakin chmod filenya agar hanya diakses oleh user itu sendiri:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
ssh tanpa password dengan key

Tentunya file key ini juga bisa dicuri orang jika berhasil masuk komputer kita (baik dari akses lokal maupun remote). Dengan memberi password, kita menambah keamanan supaya andaikan dicopy, tetap tidak bisa digunakan (tapi ini juga bisa dibruteforce offline).

Bagaimana jika kita tidak memberi password ketika membuat keynya? kita bisa menambahkan password belakangan dengan:

  ssh-keygen -p -f ~/.ssh/id_rsa

Jika private key diberi password, file public key tetap tidak berubah, jadi tidak perlu mengubah authorized_keys di host lain. Menurut saya penggunaan key ini sangat mudah dan sederhana, jadi jika mungkin beralihlah dari password ke key.

SSH agent

Jika kita memakai password untuk melindungi private key SSH, ada masalah baru: kita jadi sering perlu mengetikkan password private key-nya setiap kali login ssh. Selain itu ada masalah lain: jika saya SSH dari komputer A ke B, dan dari B ssh ke C, maka perlu key baru di B untuk masuk ke C (atau perlu copy private key A ke komputer B).

Solusi untuk kedua masalah adalah SSH agent, sebuah daemon/service yang berjalan di latar belakang yang akan “mengingat” key yang kita miliki.

SSH agent bisa menyimpan key yang kita pakai di memori, jadi key yang dienkrip bisa didekrip sekali (perlu password sekali), lalu masuk memori. Ada banyak pilihan program agent, misalnya defaultnya OpenSSH adalah ssh-agent, Putty punya pageant, dan ada banyak implementasi agen yang bisa dicari di github.

Di Windows, ketika menginstall OpenSSH, ssh-agent ini otomatis terinstall dan aktif, dan kita bisa melakukan:

ssh-add

Dan otomatis akan menambahkan semua key default ke memori. Jika ingin menambahkan key lain:

ssh-add .ssh/id_rsa2

Jika key butuh password, maka akan ditanya passwordnya apa. Jadi sekarang meskipun key diberi password, cukup sekali saja mengetikkan passwordnya (ketika memasukkan ke ssh-add).

Di Linux, ssh-agent tidak otomatis dimulai, dan kita bisa menggunakan eval $(ssh-agent) untuk memulai di sesi shell saat ini. Jika ingin otomatis, ada banyak cara untuk memulainya (bisa dengan .bashrc, systemd, dsb).

Di macOS kita bisa memakai Keychain untuk sebagai penyimpanan key, misalnya:

ssh-add --apple-use-keychain .ssh/id_rsa

Menambahkan key ke agent ini perlu dilakukan setiap kali agent dimatikan, biasanya ketika komputer dimatikan, atau ketika shell diclose, tergantung bagaimana memulai ssh-agent-nya.

SSH juga memiliki fitur ssh-agent forwarding. Ini perlu diaktifkan di file konfigurasi ssh (.ssh/config atau di global ssh_config), dengan menambah/mengeset ForwardAgent yes

Misalnya kita di laptop (sebut saja A), kita memiliki key id_rsa dan id_rsa.pub kita tambahkan ke authorized_keys di komputer B dan C. Dari A kita bisa langsung ssh ke B atau C tanpa password. Bagian ini jelas.

Jika di laptop kita set Forward Agent yes (dan key sudah ditambahkan ke agent dengan ssh-add), maka kita sekarang bisa ssh ke B (seperti biasa), dan dari B kita bisa ssh ke C (meski keynya tetap ada di laptop kita) dan tidak ada key di server B.

SSH dengan hardware key

Masalah dengan key yang berbentuk file adalah: keynya bisa dicopy oleh orang lain dan password bisa disadap (dan keduanya bisa dilakukan jika seseorang memiliki akses dari remote). Agar lebih aman, OpenSSH mendukung penggunakan berbagai hardware key. Tujuannya: meskipun attacker bisa masuk ke sebuah komputer secara remote, tetap tidak bisa menyalin keynya.

Dengan hardware key, maka key tidak bisa disalin (tidak bisa dibuat backupnya juga). Hardware hanya mematuhi perintah untuk encrypt/decrypt/sign/verify, tapi tidak akan memberikan keynya jika diminta.

Ada dua pendekatan dalam membuat key: meminta hardware membuat keynya dan menyimpannya (ini lebih aman, key tidak pernah keluar dari hardware), atau kita bisa mengimpor key yang ada ke dalam hardware (ini kurang aman, jadi yang dibahas hanya pendekatan pertama).

Jika kita kehilangan hardware-nya, maka key tidak bisa direcover, jadi sebaiknya punya key lain untuk backup akses ke server. Backup bisa berupa file key berpassword atau hardware key cadangan.

Ada hardware key yang bisa dibeli khusus (bentuknya USB atau smart card), tapi kita juga bisa memanfaatkan TPM yang sudah ada di komputer. Bagian terakhir ini yang akan saya bahas.

Jika hardware keynya berbentuk hardware portable (seperti yubikey yang bentuknya USB), maka kita akan bisa mengakses server dari mana saja selama kita memegang key ini. Hardware key ini bisa diberi password/PIN, dan jika salah sekian kali, maka keynya akan hangus (jadi tidak bisa dibruteforce).

Jika hardware keynya berbentuk TPM (yang menempel ke komputer), maka key hanya bisa diakses dari komputer/server/laptop itu saja. Ini sangat berguna jika kita hanya melakukan pekerjaan dari satu komputer/laptop saja dan sering SSH ke server lain.

TPM Ini juga bisa digunakan di kantor: hanya dari komputer itu saja seseorang bisa SSH ke server lain, tidak bisa dicopy keynya ke server lain. Akses ke komputer tersebut bisa dilog di file atau bahkan dimonitor dengan CCTV. Karena built in di dalam CPU, maka ini lebih sulit dicuri, tidak seperti hardware key berbentuk USB/smart card yang kecil.

keypair sk

Keypair sk (security-key) ini berbasis standard FIDO/U2F (saya pernah mengimplementasikan U2F di tulisan blog ini). FIDO implementasinya bisa memakai hardware key (seperti Yubikey), atau memakai support FIDO built in di Windows 10/11 (memakai PIN/Fingerprint/Face recognition atau dikenal sebagai Windows Hello).

Dulu saya mendapatkan promo cloudflare, jadi punya banyak key

Windows Hello akan memakai TPM untuk menyimpan key, jadi di sini kita memakai TPM tapi secara tidak langsung. Jika tidak tersedia fingerprint reader atau kamera infrared yang bisa dipakai, maka defaultnya Windows Hello akan memakai PIN.

Untuk laptop, biasanya ada fingerprint reader atau ada kamera yang kompatibel dengan Windows Hello. Untuk desktop, kita perlu memasukkan PIN. Tapi jika memasukkan PIN dirasa tidak praktis, Anda bisa membeli fingerprint reader atau kamera USB yang kompatibel dengan Windows Hello.

Fingerprint reader ini cocok untuk dipakai di desktop atau laptop lawas

Untuk memakai key berjenis SK, kita butuh OpenSSH (client dan server) minimal versi 8.2 (dirilis 14 Februari 2020, lebih dari 4 tahun yang lalu). Tapi sayangnya implementasi Windows perlu OpenSSH yang lebih baru, saat ini versi beta 9.5.0 bisa dipakai. Kita bisa memakai winget untuk menginstallnya:

winget install --id=Microsoft.OpenSSH.Beta

Ada dua jenis key ecdsa-sk dan ed25519-sk, saat ini tidak terlalu penting yang mana yang dipakai, tapi sebagian hardware key FIDO hanya mendukung ecdsa-sk.

Setelah memakai OpenSSH terbaru di Windows, kita bisa membuat key dengan:

ssh-keygen -t ecdsa-sk

Kita akan diminta autentikasi Windows Hello.

Membuat key ecdsa-sk

Public key bisa dilihat di .ssh/id_ecdsa_sk.pub, dan file ini bisa dicopy ke remote host sama seperti ketika kita menggunakan ssh-copy-id atau manual copas ke authorized_keys. Bedanya login dengan file key biasa: ketika kita login akan keluar opsi untuk memakai fingerprint/pin/wajah.

Untuk Anda yang hanya memakai satu key di satu komputer, perintah di atas sudah cukup. Untuk yang memakai key yang dipindah-pindah, silakan baca lagi manual FIDO untuk SSH.

Key sk/FIDO ini bisa juga dipakai di Linux. Sayangnya Linux tidak memiliki fitur FIDO built-in, jadi kita perlu membeli hardware eksternal (misalnya Yubikey) atau bisa menggunakan menggunakan tpm-fido yang mengemulasikan FIDO dengan TPM.

Untuk macOS agak repot saat ini support FIDO perlu diakali di macOS. Ada banyak cara lebih mudah memaka Touch ID di macOS, misalnya dengan secretive atau secure agent.

PKCS

PKCS (Public-key Cryptography Standards ) merupakan interface standard untuk berkomunikasi dengan token kriptografi. Catatan: nama benar standard ini adalah PKCS#11, tapi banyak bahasa pemrograman tidak mendukung # di dalam nama identifiernya, jadi sering juga ditulis sebagai PKCS11.

SSH bisa berkomunikasi dengan segala macam smart card atau device lain (atau emulator) yang mengimplementasikan standard PKCS#11 ini. TPM sendiri tidak mengimplementasikan standard ini, tapi sudah ada yang membuat modul agar SSH bisa berkomunikasi dengan TPM.

Apa bedanya dengan memakai FIDO? FIDO butuh server SSH yang relatif baru (jenis keynya baru). Pendekatan PKCS#11 ini tidak butuh jenis key baru, bisa jalan di server mana saja yang mendukung key RSA/ECC standard. Key juga bisa ditambahkan ke ssh-agent.

Saya akan mencontohkan di Debian saja, untuk distribusi Linux lain seharusnya serupa (mungkin pathnya berbeda). Pertama kita install library dan tools agar TPM dan SSH bisa berkomunikasi:

sudo apt install libtpm2-pkcs11-tools libtpm2-pkcs11-1

Kita juga perlu memastikan bahwa user masuk ke group tss : sudo usermod -a -G tss $(whoami). Logout lalu login lagi supaya perubahannya berlaku, atau gunakan newgrp tss.

Berikutnya : tpm2_ptool init untuk menginisialisasi TPM. Lalu kita membuat bisa token:

tpm2_ptool addtoken --pid=1 --label=ssh --userpin=MySecretPassword --sopin=MyRecoveryPassword

Yang paling penting: ingat SOPIN (security officer PIN), yang bisa dipakai untuk mereset user PIN. User PIN ini yang nanti akan sering dipakai/diketik ketika butuh mengakses TPM. Meskipun namanya PIN, ini bisa berupa karakter apa saja, tidak cuma angka.

Berikutnya kita bisa membuat key baru (label disamakan dengan nama token sebelumnya: ssh)

tpm2_ptool addkey --label=ssh --userpin=MySecretPassword --algorithm=rsa2048

Selain RSA, kita bisa membuat key lain misalnya ecc256. Sekarang kita bisa menampilkan public keynya:

 ssh-keygen -D /usr/lib/x86_64-linux-gnu/libtpm2_pkcs11.so.1

Ini bisa dicopy ke host target (sama seperti key biasa). Setelah itu tambahkan

PKCS11Provider /usr/lib/x86_64-linux-gnu/libtpm2_pkcs11.so.1

Di .ssh/config agar key yang tersimpan di TPM bisa digunakan. Ketika SSH kita akan ditanya userpin yang sudah dimasukkan tadi. Jika tidak ingin ditanya terus, gunakan agent:

ssh-add -s  /usr/lib/x86_64-linux-gnu/libtpm2_pkcs11.so.1
ssh-agent dengan pkcs#11

Meski keliatannya sama saja dengan memakai key biasa, tapi key berbasis TPM tidak bisa dicopy, dan tidak bisa dibruteforce (akan terkunci).

Penutup

Memakai key berbasis hardware (apalagi sekedar fingerprint) menurut saya lebih praktis dan aman daripada mengetikkan password. Dulu solusi hardware memang mahal, tapi sekarang sudah ada yang built in, dan jika ingin membeli fingerprint reader yang kompatibel dengan Windows Hello harganya juga sudah relatif murah, saat ini sekitar 10 USD (kurang dari 200 ribu rupiah).

Apakah ini 100% aman? tentu tidak ada yang 100% aman, laptop bisa dicuri, dan fingerprint Anda bisa disalin dari benda yang Anda sentuh. Apapun yang terhubung ke internet bisa dihack.

Andaikan key ada di laptop dan ada di dalam TPM, lalu ada yang bisa mengendalikan komputer secara remote, dan attacker memiliki PIN untuk TPM, maka attacker bisa menggunakan laptop Anda jadi proxy untuk masuk ke server target. Jadi ini tidak 100% aman, tapi sangat mempersulit attacker. Jika kita selalu menggunakan fingerprint, attacker tidak mungkin mendapatkan akses ke TPM tanpa berapa di depan laptop kita (kecuali ada bug di driver fingerprintnya atau di dalam sistem Windowsnya).

Untuk Anda yang masih belajar, bisa mencoba-coba dulu minimal memakai autentikasi berbasis file keypair, dan jika sudah yakin, bisa mencoba menggunakan autentikasi berbasis key yang di hardware.

Apa yang saya tuliskan di sini semuanya masih sangat dasar, SSH memiliki banyak opsi. Sudah ada banyak buku yang ditulis mengenai SSH walau kebanyakan belum diupdate dengan fitur-fitur SSH terbaru, jadi gunakan internet untuk mendapatkan informasi tambahan terbaru.

Untuk Anda yang di perusahaan besar, masih banyak solusi autentikasi lain yang tidak dibahas di sini. Biasanya yang dipakai adalah kombinasi Public Key Infrastructure (PKI) dengan tambahan smartcard.

Selain apa yang saya tulis, banyak yang membuat tool untuk memudahkan di berbagai OS. Tanggung jawab Anda untuk memastikan bahwa tool-tool tersebut bisa dipercaya dan malah tidak membuat backdoor baru.

Tinggalkan Balasan

Situs ini menggunakan Akismet untuk mengurangi spam. Pelajari bagaimana data komentar Anda diproses.