Ç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 "your@email.com"
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 emre@myhost.local
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= emre.yildirim@mryldrm.com
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;
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.
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 git@bitbucket.org:my-project/repo.git
yerine git clone git@server2.bitbucket.org: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