post-images/multiple-ssh-key-management/cover.jpg

Çoklu SSH Key Yönetimi

Bugün yaşadığım bir olayı hem kaydetmek hem de senin yararlanabilmen için yazıya almak istedim.

Halihazırda bir SSH key tanımı olan sunucuda başka bir ssh key tanımlamak istediğimizde mevcutta bulunan SSH key'e dokunmak istemeyebilirsin. Bu durumda nasıl bir yöntem izleyebileceğini aktaracağım.

Konunun kaynağına geri sararsak; Herhangi bir makinede git sunucumuzdaki (Github, Bitbucket, GitLab vb.) kodlara erişmek veya yönetmek istediğimizde aşağıdaki şekilde bir hata ile karşılaşabilirsin. Bu mesaj, makinen (sunucu, local) ile git sunucun arasında el sıkışılamadığını özetle makinende bulunan SSH key ile git sunucunda ki access key birbiriyle eşleşmediğini söylüyor.

#GitHub
ssh: Could not resolve hostname github.com:username: nodename nor servname provided, or not known
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
#Bitbucket
ssh: Could not resolve hostname bitbucket.org: Name or service not known
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Bu sorunu çözmek için makinende bir SSH key üretmen (id_rsa, id_rsa.pub) ve üretmiş olduğun bu key'in public olanını (id_rsa.pub) git sunucuna tanımlaman gerekiyor. Bu sayede repona erişmek istediğinde bu iki key karşılaştırılacak ve birbiri ile erişirse kimliğin doğrulanmış (authenticate) olacak. Bu işlem sonrası herhangi bir sorun yaşamadan git sunucundaki kodları makinenden yönetebilirsin.

Bu süreci adım adım ilerletecek olursak;

SSH Key Oluşturma:

$ ssh-keygen -t rsa -b 4096 -C "[email protected]" 

Komut girildikten sonra aşağıdaki şekilde bir uyarı ile karşılacaksın. .ssh dizini default olarak $HOME dizinini işaret edecektir. Bu kısım bizim için önemli, gerek duymadıkça değiştirmeyin.

Generating public/private rsa key pair.  
Enter file in which to save the key (/home/emre/.ssh/id_rsa):

Sonuç olarak aşağıdaki şekilde bir ekran ile karşılaşman gerekiyor.

$ ssh-keygen  
Generating public/private rsa key pair.  
Enter file in which to save the key (/home/emre/.ssh/id_rsa):  
Created directory '/home/emre/.ssh'.  
Enter passphrase (empty for no passphrase):  
Enter same passphrase again:  
Your identification has been saved in //home/emre/.ssh/id_rsa.  
Your public key has been saved in /home/emre/.ssh/id_rsa.pub.  
The key fingerprint is:  
4c:80:61:2c:00:3f:9d:dc:08:41:2e:c0:cf:b9:17:69 [email protected]  
The key's randomart image is:  
+--[ RSA 2048]----+  
|*o+ooo.          |  
|.+.=o+ . 	  |  
|. *.* o . 	  |  
| . = E o 	  |  
| o . S 	  |  
| . . 		  |  
| . 		  |  
| 	          |  
| 	          |  
+-----------------+

Oluşan public key'i görmek için:

$ ls ~/.ssh
id_rsa id_rsa.pub

Bu komut, biri public key ( id_rsa.pub ) ve diğeri private key ( id_rsa ) için olmak üzere iki dosya gösterir.

$ cat id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFQAAAAdzc2gtcn
NhAAAAAwEAAQAAAf8rzyak4sv8oWg2j2XC3zdUogh2639L1UsHUog/8rICc/QnKAJeZrfI
vsHHm9u3mrCYojZ9YmnNNK1lrSdE5lZzfrqfcEkIkC93ghoW+ijEpPvcOpfp8UN9ikedpj
...
fQgfdDa31aFAAABxlbXJlLnlpbGRpcmlt3f5ADAgdAQHNhaGliaW5kZW4uY29tAQIDBA==
-----END OPENSSH PRIVATE KEY-----
$ cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB/yvPJqTiy/yhaDaPZcLfN1SiCHbrf0vVa
SwdSiD/ysgJz9CcoAl5mt8i+wceb27easJiiNn1iac00rWWtJ0TmVnN+up9wSQiQL3eC4
a2OZjbm0j79W9QDzSJtSBvpoRSyc+5jg6X2APtS/r+StOoeqAebMOrO3+ENtIkL2+97M5
....
afgZ1FAS0TrZGeQrvX0aXWagXZ856NoFHexNAaMems= [email protected]

Artık makinemize özel SSH keyimiz mevcut. Üretmiş olduğumuz public key dosyasının içeriğini tamamen kopyalayıp git sunucumuza eklememiz gerekiyor.

SSH Kopyalama Kısayolu

Windows

clip < id_rsa.pub

Mac OS X

pbcopy < ~/.ssh/id_rsa.pub

Linux

xclip -sel clip < ~/.ssh/id_rsa.pub

GitHub için SSH key tanımlama Official Doc: Adding a new SSH key to your GitHub account

Bitbucket için için SSH key tanımlama Official Doc: SSH access keys for system use

Çoklu SSH Tanımlama

Yazıyı yazma nedenim ve karşıma çıkan istisna olaya gelecek olursak; Yukarıdaki bilgiler ışığında bir makinemiz olsun ve bu makinemiz için SSH keylerimizi oluşturduğumuzu ve git sunucumuzda da tanımlamaları yaptığımızı varsayalım.

Durumumu ele alırsak, sunucumuzdan bir başka git sunucusuna erişme ihtiyacı doğduğunda veya yeni bir repoya erişmek istediğimizde ne yapacağız? Aynı şekilde daha önceden oluşturduğumuz id_rsa.pub'i yeni git sunucusu veya repo için tanımlayabiliriz. Fakat olay içerisine yetkilendirme girdiğinde ortalık biraz karışıyor. Şöyle ki;

root design

Yukarıdaki gibi bir yapımız olduğunu varsayalım. Bir adet ana sunucumuz ( root ) olduğunu düşünelim. Bu ana sunucununda kendi içinde n adet sanal sunucu oluşturabildiğini ( S1, S2, S3... ) varsayalım. Bu durumda tek tek tüm sunuculara SSH atamaktansa root'un sahip olduğu profili tüm sunuculara aktarıp root'un SSH keyini git sunucusuna tanımlamak güzel bir çözüm. Bu sayede tüm alt sunucular aynı SSH key ile git'e erişebiliyor olacak.

Peki sadece bir sunucudan farklı bir git sunucusuna veya repoya erişilsin fakat diğer sunuculardan buraya erişim olmamasını istersek ne yapacağız? Sadece spesifik bir sunucunun kodlara erişimi olmasını isteyebiliriz. sub server design

Farklılaşmasını istediğimiz sunucu için yeni bir SSH key oluşturabiliriz. Bu durumda da karşımıza asıl SSH key'in ( id_rsa ) override edilmesi sorunu geliyor. Yeni SSH key oluşturursak eski SSH key değişeceğinden eski SSH key ile bağlandığımız tüm sunuculara erişim sorunu yaşayacağız. Bir çözüm yöntemi olarak id_rsa dosyasını override etmeden yeni isimde bir key oluşturabilirim ( server1.pub ). Fakat burada da şu sorun var bağlanmak istediğimiz sunucular default dizin olan ~/.ssh/id_rsa.pub dosyasına bakacaktır. Benim oluşturduğum ~/.ssh/server1.pub'a değil. Bu sorunu da çözmenin bir yolu var: SSH'ın yapılandırılması.

SSH Yapılandırma (SSH Configuration)

~/.ssh/ içinde, config adlı bir dosya oluşturun ve içerisine yönlendirmek istediğiniz tanımları ekleyin.

#root
Host root
    HostName github.com
    User root
    IdentityFile ~/.ssh/id_rsa
    IdentitiesOnly yes
     
#server1
Host server1
    HostName bitbucket.org
    User server1
    IdentityFile ~/.ssh/server1
    IdentitiesOnly yes

#server2
Host server2
    HostName bitbucket.org
    User server2
    IdentityFile ~/.ssh/server2
    IdentitiesOnly yes
...

Bir sunucu GitHub'ı diğer bir sunucu bitbucket'ı kullandığında yönlendirme sorunu yaşamazsın fakat iki sunucu da aynı git sunucusu altındaki repoya yönlenmesi gerektiği durumda ( server1 ve server2'in bitbucket'a gitmesi gibi ) sahte bir alt alan adı ile erişebilirsin. git clone [email protected]:my-project/repo.git yerine git clone [email protected]:my-project/repo.git kullanabilirsin.

Yazıyı bitirmeden önce şu taktikten de bahsetmek istiyorum. "Kullanıcı bazlı ayrıştırmak istemiyorum. Sunucuda, git sunucusuna erişmemi sağlayacak bir SSH key varsa bana ver" diyorsan aşağıdaki şekilde config dosyanı değiştirebilirsin.

Host *
    IdentityFile ~/.ssh/id_rsa
    IdentityFile ~/.ssh/server1
SSHSSH KeysSSH ConfigurationGitGitHubBitbucket