1 Haziran 2020 Pazartesi

ssh İle Karşı Sunucuda Komut Çalıştırma

Giriş

1. Karşı Sunucuda Açılan Shell
ssh ile karşıdaki sunucuya giriş yaptıktan sonra bizim için bir tane shell açılır. Bu shell kullanıcı ayarlarında ne tanımlı ise o shell'dir. Dolayısıyla komutun içine tekrar bash yazmaya gerek yok.

Örnek
Şu komut istenileni vermez. Çünkü bir daha bash çalıştırılmaya çalışılıyor
$ ssh remote bash -c 'ls file-*'
Şöyle yaparız.
$ ssh remote ls file-*'
2.Seçenekler
-n seçeneği
Örnek
Elimizde şöyle bir kod olsun.  Bu kod sadece ilk sunucuda çalışır.
#!/bin/sh
SERVERLIST=hosts
ICMD='cat /etc/redhat-release'
while read SERVERNAME
do
   ssh $SERVERNAME $ICMD
done < "$SERVERLIST"
Açıklaması şöyle
ssh pre-reads stdin on the assumption that the remote job will want some data, and it makes for a faster start-up. So the first job eats the rest of your hosts list.

You can prevent this happening either using the ssh -n option, or by redirecting like ssh < /dev/null. Being a belt-and-braces man, I do both: ssh -n < /dev/null <other ssh options>.
Düzeltmek için şöyle yaparız
#!/bin/sh
SERVERLIST=servername.dat
ICMD='cat /etc/fstab'
while read SERVERNAME
do
   ssh -n $SERVERNAME $ICMD > $SERVERNAME_report.txt
done < "$SERVERLIST"
-t seçeneği
Shell'e ait bir tty olmak zorunda değildir. Bu durumda -t seçeneği ile birlikte kullanılır. Açıklaması şöyle. Eğer -t seçeneği bir kere kullanılırsa pseudo tty açılır. Eğer iki kere kullanılırsa gerçek tty açılır
-t   Force pseudo-tty allocation.  This can be used to execute arbi-
     trary screen-based programs on a remote machine, which can be
     very useful, e.g. when implementing menu services.  Multiple -t
     options force tty allocation, even if ssh has no local tty.
Şöyle yaparız.
ssh -tt user@ip 'ls -la; bash'

3. Çeşitli Örnekler

Komut Genellikle Tek Tırnak İçinde Gönderilir
Tek tırnak  ile raw string gibi hiç bir işleme uğramadan gönderilir. bash kodlama - tırnak yazısına bakabilirsiniz.

Örnek - bash
Şöyle yaparız. Tek tırnak içindeki kısım aynen karşı tarafa gönderilir.
ssh root@host 'bash -s' < command1
Örnek
Komut bitince ssh içinde kalmak için şöyle yaparız. Tek tırnak içindeki kısım aynen karşı tarafa gönderilir.
ssh -t -p port_num user@remote
  bash --init-file '<(echo "sudo docker logs -f service_name")'
Örnek - bash Here Document
"Here Document" yöntemi ile birden fazla komut çalıştırmak için şöyle yaparız.
ssh otherhost << EOF
  ls some_folder; 
  ./someaction.sh 'some params'
  pwd
  ./some_other_action 'other params'
EOF
Örnek - bash Here Document
"Here Document" yöntemi ile birden fazla komut çalıştırmak için şöyle yaparız.
ssh -t -p port_num user@remote << HERE
> sudo su -
> docker logs -f service_name
> HERE
Örnek - bash Here Document
Şöyle yaparız. Burada komutumuz içinde de tek tırnak olduğu için Here Documen kullanmak daha iyi.
ssh server.name /bin/sh <<'EOF'
find /dir1/subdir/filelist* -maxdepth 1 -type f -mtime 0 -exec grep 'pattern' {} \;
EOF
Örnek - cat komutu
Şöyle yaparız. gzip dosyayı stdout'a yazar. Onu da ssh okur ve cat komutuna verir. Cat komutu da dosyaya yazar.
gzip -c file.txt | ssh user@ip "cat > destfile.gz"
Örnek - echo komutu
Karşı sunucundaki bash sürümünü öğrenmek için şöyle yaparız. Tek tırnak içindeki kısım aynen karşı tarafa gönderilir.
ssh me@somehost 'echo "$BASH_VERSION"'
Örnek - poweroff komutu
Şöyle yaparız.
ssh 192.168.1.10 "sudo poweroff"
Örnek - ssh çıktısını subshell içinde yapmak
ssh çıktısını almak için şöyle yaparız. Burada subshell içindeki ssh benim stdin'inimi okumasın isteniyor. Bir başka örnek burada
http_status=$(ssh $name "ps -ef | grep -v grep | grep $service | wc -l" 
  < /dev/null)
Örnek - ssh çıktısını yönlendirme
Şöyle yaparız
ssh -l user $IP "dd if=/dev/zero count=3500 bs=1M status=progress" > /dev/null
Örnek - ssh girdisi subshell
Kendi bilgisayarımdaki bir şeyi karşıya göndermek için subshell açarım. Şöyle yaparız. Kendi saatimi karşı tarafın saatine değiştirmek için kullanırım
ssh pi@hostname.local sudo date -s$(date -Ins)
Örnek - ssh girdisinde boşluk olması
Şöyle yaparız. Burada print sonucunda içinde boşluk olan bir çıktı üretiliyor. Bunu ssh komutuna geçiyoruz. ssh ta karşı makinede çalışacak xargs komutuna geçiyor
printf '%s\0' "$DEST_PATH/subdir1" "$DEST_PATH/subdir2" |
  ssh -i key 10.10.10.10 'xargs -0 mkdir -p --'
Örnek - ssh çıktısı
Bağlanıncaya kadar tekrar etmek için ~/.bashrc dosyasına şöyle yaparız
repeat()
{
read -p "Enter the hostname or IP of your server :" servername
until ssh $servername; do
    sleep 5
done
}

update-ca komutu

Örnek
Bir tane root sertifikayı güncellemek isteyelim. Önce sertifikayı silmek için şöyle yaparız
sudo rm /usr/share/ca-certificates/mozilla/AddTrust_External_Root.crt
Daha sonra şöyle yaparız
sudo update-ca-certificates

openssl x509 aracı

Giriş
X509 sertifikaları ile çalışmak içindir. X509 aracı şu işler için kullanılır.
1. View
2. Transform
3. Combination
4. Extraction

1. View
- "-in certificate_ path" seçeneği ile okunacak sertifika dosyası belirtilir veya
- pipe ile sertifika bu komuta verilir

--dates seçeneği
Örnek
Sertifikadaki bir alanı görmek için şöyle yaparız
$ echo | 
  openssl s_client -servername {SERVER_NAME} -connect {SERVER_NAME}:{PORT} | 
  openssl x509 -noout -dates
-inform seçeneği
Normalde sertifikanın x509 formatında olması beklenir. Eğer başka bir formattaysa - örneğin DER - bunu belirtmek için kullanılır
Örnek
Şöyle yaparız. Burada -issuer ile issuer ismi, -nameopt ile name isminin gösterilmesi de belirtiliyor.
openssl x509 -in <pathToClientPEM> -inform PEM -subject -nameopt RFC2253
Çıktı olarak şunu alırız
subject= CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry
-----BEGIN CERTIFICATE-----
# ...
-----END CERTIFICATE-----
-modulus seçeneği
Sertifikanın sadece modulus kısmın gösterir.
Örnek
Şöyle yaparız
openssl x509 -noout -modulus -in myserver.crt
-issuer seçeneği
issuer ismini gösterir
Örnek
Şöyle yaparız
openssl x509 -issuer -enddate -noout 
  -in /usr/share/ca-certificates/mozilla/AddTrust_External_Root.crt
Çıktı olarak şunu alırız
issuer=C = SE, O = AddTrust AB, OU = AddTrust External TTP Network,
 CN = AddTrust External CA Root
notAfter=May 30 10:48:38 2020 GMT
-noout seçeneği
encoded çıktının gösterilmesini engeller. 
Örnek
Şöyle yaparız
openssl x509 -in myserver.crt -text -noout
-text seçeneği
Sertifikanın tam halini text olarak gösterir
Örnek
PEM kodeği ile kaydedilmiş bir dosyayı görmek için şöyle yaparız
openssl x509 -in cert.pem -noout -text
Örnek
PEM kodeği ile kaydedilmiş bir dosyayı görmek için şöyle yaparız.
openssl x509 -in localhost.pem -text -noout

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            c2:a8:fc:a1:29:02:96:dd
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: ...
        Validity
            Not Before: Apr  7 02:25:51 2018 GMT
            Not After : Mar 14 02:25:51 2118 GMT
        Subject: ...
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    ...
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                D6:DF:EB:FA:73:85:C9:22:AA:6D:79:E5:F9:16:01:2B:CC:E7:D8:D0
            X509v3 Authority Key Identifier: 
                keyid:D6:DF:EB:FA:73:85:C9:22:AA:6D:79:E5:F9:16:01:2B:CC:E7:D8:D0

            X509v3 Basic Constraints: critical
                CA:TRUE
    Signature Algorithm: sha256WithRSAEncryption
        ...
Örnek
DER kodeği ile kaydedilmiş bir dosyayı görmek için şöyle yaparız.
$ openssl x509 -inform der -in ca.skole.hr.der -noout -text
Certificate:
  Data:
    Version: 3 (0x2)
    Serial Number: 0 (0x0)
    Signature Algorithm: sha1WithRSAEncryption
    Issuer: C = HR, ST = Zagreb, L = Zagreb, O = MZOS, OU = CARNet,
            CN = CA Root certificate skole.hr
    Validity
      Not Before: Nov 15 14:17:58 2011 GMT
      Not After : Nov 12 14:17:58 2021 GMT
    Subject: C = HR, ST = Zagreb, L = Zagreb, O = MZOS, OU = CARNet,
             CN = CA Root certificate skole.hr
    Subject Public Key Info:
      Public Key Algorithm: rsaEncryption
        RSA Public-Key: (1024 bit)
        Modulus:
          ...
        Exponent: 65537 (0x10001)
    X509v3 extensions:
      X509v3 Subject Key Identifier: 
        00:e5:a0:99:17:88:9d:1c:9300:e5:a0:99:17:88:9d:1c:93
      X509v3 Authority Key Identifier: 
        keyid:00:e5:a0:99:17:88:9d:1c:93:00:e5:a0:99:17:88:9d:1c:93:00:e5:a0

            X509v3 Basic Constraints: 
                CA:TRUE
    Signature Algorithm: sha1WithRSAEncryption
         ...
2. Transform
Dijital sertifikayı bir başka kodek kullanarak çevirir.
Örnek
PEM kodeği ile kaydedilmiş dosyayı DER kodeği ile kaydetmek istersek şöyle yaparız.
openssl x509 -in cacert.pem -out cacert.cer -outform DER
3. Combination
İki dosyayı birleştirir.

4. Extraction
Birleştirilmiş dosyaları ayırır.

5. CSR imzalamak
Örnek
Önce bir Private key yaratırız. Şöyle yaparız
$ openssl genrsa -out rohan.key 2048
Daha sonra CSR yaratmak için şöyle yaparız
$ openssl req -new -key rohan.key -out rohan.csr -sub "/CN=rohan/0=marketingweb"

$ ll
... rohan.csr
... rohan.key
CSR'den sertifika üretmek için şöyle yaparız. Burada minikube'a ait certificate authorities ve private key kullanılıyor.
openssl x509 -req rohan.csr 
  -CA ../minikube/ca.crt ../minikube/ca.key 
  -CAcreateserial -out rohan.crt -days 365


nc komutu - netcat

Giriş
nc netcat anlamına gelir. Aklımda hep netchat olarak kalıyor :) Bu komuta alternatif olarak socat komutu da kullanılabilir.

Bazı yerlerde nc yerine ncat komutu da kullanılıyor. İkisi de aynı şey

Windows Kurulum
https://nmap.org/dist/ adresinden setup.exe indirilir ve kurulur. Bundan sonra komut satırıından ncat kullanılabilir

Sürümler
İki tane farklı netcat sürümü var.
1. netcat-traditional - Eski olan
2. netcat-openbsd - Yeni olan
Farkları şöyle
$ apt-cache show netcat-traditional 
...
 This is the "classic" netcat, written by *Hobbit*. It lacks many
 features found in netcat-openbsd.
...
$ apt-cache show netcat-openbsd 
...
 This package contains the OpenBSD rewrite of netcat, including support
 for IPv6, proxies, and Unix sockets.
...
Kullanım
Bir sunucuya bağlanmak için şöyle yaparız.
netcat localhost 4444
-4 seçeneği
IPv4 kullanmak istediğimizi belirtir
Örnek
Sunucuya IPv4 ile bağlanmak için şöyle yaparız
nc -4 localhost 8080
-l seçeneği - listen mode, for inbound connects
Sunucu açar. Eğer protokolü belirtmezsek TCP sunucudur. Şöyle yaparız.
netcat -l localhost 8087 <<< '"status":"okay", "id":"game-23", "letter":2'
-n seçeneği - numeric-only IP addresses, no DNS
DNS kullanmamayı sağlar. Şöyle yaparız.
nc -n localhost 9999
-p seçeneği -  local port number
UDP sunucusu açmak için şöyle yaparız.
nc -l -u -p 5006
-u seçeneği - UDP mode
Örnek
UDP sunucusu açmak için şöyle yaparız.
nc -l -u -p 5006
Örnek
UDP paketi göndermek için şöyle yaparız.
echo -n 1234567890| nc -u 224.4.4.4 1234
-w seçeneği - timeout for connects and final net reads

timeout süresini belirtir. Şöyle yaparız.
nc -w 1 -zv host1
-v seçeneği
verbose (daha detaylı) gösterir. Açıklaması şöyle.
enables verbose mode

-z seçeneği - port scanning içindir
Karşı sunucudaki portları taramak için kullanılır. Sadece bağlantı açar ve veri göndermez. Yani I/O yapmaz. Açıklaması şöyle.
sets nc to simply scan for listening daemons, without actually sending any data to them
Bir başka açıklama şöyle.
It may be useful to know which ports are open and running services on a target machine.  The -z flag can be used to tell nc to report open ports, rather than initiate a connection. Usually it's useful to turn on verbose output to stderr by use this option in conjunction with -v option.

 For example:

       $ nc -zv host.example.com 20-30
       Connection to host.example.com 22 port [tcp/ssh] succeeded!
       Connection to host.example.com 25 port [tcp/smtp] succeeded!

 The port range was specified to limit the search to ports 20 - 30, and is scanned by increasing order (unless the -r flag is set).

 You can also specify a list of ports to scan, for example:

       $ nc -zv host.example.com http 20 22-23
       nc: connect to host.example.com 80 (tcp) failed: Connection refused
       nc: connect to host.example.com 20 (tcp) failed: Connection refused
       Connection to host.example.com port [tcp/ssh] succeeded!
       nc: connect to host.example.com 23 (tcp) failed: Connection refused

 The ports are scanned by the order you given (unless the -r flag is set).

 Alternatively, it might be useful to know which server software is running, and which versions.  This information is often contained within the greeting banners.  In order to retrieve these, it is necessary to first make a connection, and then break the connection when the banner has been retrieved.  This can be accomplished by specifying a small timeout with the -w flag, or perhaps by issuing a "QUIT" command to the server:

       $ echo "QUIT" | nc host.example.com 20-30
       SSH-1.99-OpenSSH_3.6.1p2
       Protocol mismatch.
       220 host.example.com IMS SMTP Receiver Version 0.84 Ready
Örnek
Şöyle yaparız.
nc -zv kafka02 6667