SPA z wykorzystaniem kluczy GPG/PGP

Kategoria: Artykuły, etykiety: fwknop, gpg, pgp, single packet authorization, spa, ssh

Dodany: 2014-08-10 20:41
Przez: morfik

Wyświetleń: 7163

Jakiś czas temu opisywałem jak zastosować w praktyce mechanizm SPA (Single Packet Authorization) ale tamten opis dotyczył głównie wykorzystania szyfrów symetrycznych. Istnieje też możliwość zaprzęgnięcia kluczy GPG, tak by uwierzytelnianie oraz szyfrowanie odbywało się przy ich pomocy.

By móc skorzystać z opcji kluczy szyfrujących, musimy posiadać odpowiednie klucze -- po jednym dla klienta oraz dla serwera. W przypadku wielu klientów można dla każdego z nich wygenerować osobny klucz, można również korzystać z tego samego klucza w przypadku wszystkich klientów. Jeśli chodzi jeszcze o maszyny klienckie, to można skorzystać z normalnego klucza GPG wykorzystywanego np. do szyfrowania poczty. Dla serwera trzeba stworzyć nowy klucz, a to ze względu na fakt, że hasło do tego klucza musi zostać zapisane w pliku /etc/fwknop/access.conf , a bez hasła, fwknop nie odszyfruje wiadomości otrzymanych od klienta.

Korzystanie z kluczy GPG w SPA ma jedno ograniczenie -- jako, że wiadomość musi się zawrzeć w jednym pakiecie IP, na serwerze zalecane jest by wybrać rozmiar klucza max 2048 bitów.

Przystępujemy zatem do generowania kluczy GPG. Najpierw na serwerze:

# gpg --gen-key
gpg (GnuPG) 1.4.18; Copyright (C) 2014 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 2048
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 0
Key does not expire at all
Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: Fwknop Server
Email address: server@server.org
Comment: fwknop server
You selected this USER-ID:
    "Fwknop Server (fwknop server) <server@server.org>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
You need a Passphrase to protect your secret key.

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy! (Need 119 more bytes)

+++++
gpg: key 0x72F3A416B820057A marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   2  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 2u
gpg: next trustdb check due at 2017-07-15
pub   2048R/0x72F3A416B820057A 2014-08-08
      Key fingerprint = 9F30 BD23 F4A2 3921 5E29  A3B6 72F3 A416 B820 057A
uid                 [ultimate] Fwknop Server (fwknop server) <server@server.org>
sub   2048R/0x46DF79598289C782 2014-08-08

Sprawdzamy czy klucz został dodany do keyringa GPG:

# gpg --list-secret-keys
/root/.gnupg/secring.gpg
-------------------------------
sec   2048R/0x72F3A416B820057A 2014-08-08
      Key fingerprint = 9F30 BD23 F4A2 3921 5E29  A3B6 72F3 A416 B820 057A
uid                            Fwknop Server (fwknop server) <server@server.org>
ssb   2048R/0x46DF79598289C782 2014-08-08

Klucz teraz trzeba wyeksportować do pliku (format ASCII):

# gpg -a --export 0x72F3A416B820057A > server.asc
# ls -al server.asc
-rw-r--r-- 1 root root 1.7K Aug  8 11:24 server.asc

Podobne operacje wykonujemy na kliencie:

$ gpg --gen-key
gpg (GnuPG) 1.4.18; Copyright (C) 2014 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 2048
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 0
Key does not expire at all
Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: Fwknop Client
Email address: client@client.org
Comment: client
You selected this USER-ID:
    "Fwknop Client (client) <client@client.org>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
You need a Passphrase to protect your secret key.

gpg: gpg-agent is not available in this session
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy! (Need 124 more bytes)
+++++

gpg: key 0xFFE5312387B46932 marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   2  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 2u
pub   2048R/0xFFE5312387B46932 2014-08-08
      Key fingerprint = C43F 95ED CBD4 6590 6184  2238 FFE5 3123 87B4 6932
uid                 [ultimate] Fwknop Client (client) <client@client.org>
sub   2048R/0x499820E496A32419 2014-08-08

$ gpg --list-secret-keys
/home/morfik/.gnupg/secring.gpg
-------------------------------
sec   2048R/0xFFE5312387B46932 2014-08-08
      Key fingerprint = C43F 95ED CBD4 6590 6184  2238 FFE5 3123 87B4 6932
uid                            Fwknop Client (client) <client@client.org>
ssb   2048R/0x499820E496A32419 2014-08-08

$ gpg -a --export 0xFFE5312387B46932 > client.asc

$ ls -al client.asc
-rw-r--r-- 1 morfik morfik 1696 Aug  8 11:38 client.asc

Teraz z maszyny klienckiej przesyłamy klucze przy pomocy scp:

$ scp ./client.asc root@192.168.1.150:/root/
morfik@192.168.1.150's password:
client.asc                                                 100% 1696     1.7KB/s   00:00

$ scp root@192.168.1.150:/root/server.asc ./
morfik@192.168.1.150's password:
server.asc                                                 100% 1704     1.7KB/s   00:00

W tej chwili powinniśmy mieć kopie kluczy publicznych zarówno na serwerze jak i na kliencie. Importujemy je do keyringa GPG i podpisujemy.

Na serwerze:

# gpg --import ./client.asc
gpg: key 0xFFE5312387B46932: public key "Fwknop Client (client) <client@client.org>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

# gpg -u 0x72F3A416B820057A --edit-key 0xFFE5312387B46932
gpg (GnuPG) 1.4.18; Copyright (C) 2014 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.


pub  2048R/0xFFE5312387B46932  created: 2014-08-08  expires: never       usage: SC
                               trust: unknown       validity: unknown
sub  2048R/0x499820E496A32419  created: 2014-08-08  expires: never       usage: E
[ unknown] (1). Fwknop Client (client) <client@client.org>

gpg> sign

pub  2048R/0xFFE5312387B46932  created: 2014-08-08  expires: never       usage: SC
                               trust: unknown       validity: unknown
 Primary key fingerprint: C43F 95ED CBD4 6590 6184  2238 FFE5 3123 87B4 6932

     Fwknop Client (client) <client@client.org>

Are you sure that you want to sign this key with your
key "Fwknop Server (fwknop server) <server@server.org>" (0x72F3A416B820057A)

Really sign? (y/N) y

You need a passphrase to unlock the secret key for
user: "Fwknop Server (fwknop server) <server@server.org>"
2048-bit RSA key, ID 0x72F3A416B820057A, created 2014-08-08

Na kliencie:

$ gpg --import server.asc
gpg: key 0x72F3A416B820057A: public key "Fwknop Server (fwknop server) <server@server.org>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

$ gpg -u 0xFFE5312387B46932 --edit-key 0x72F3A416B820057A
gpg (GnuPG) 1.4.18; Copyright (C) 2014 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.


pub  2048R/0x72F3A416B820057A  created: 2014-08-08  expires: never       usage: SC
                               trust: unknown       validity: unknown
sub  2048R/0x46DF79598289C782  created: 2014-08-08  expires: never       usage: E
[ unknown] (1). Fwknop Server (fwknop server) <server@server.org>

gpg> sign

pub  2048R/0x72F3A416B820057A  created: 2014-08-08  expires: never       usage: SC
                               trust: unknown       validity: unknown
 Primary key fingerprint: 9F30 BD23 F4A2 3921 5E29  A3B6 72F3 A416 B820 057A

     Fwknop Server (fwknop server) <server@server.org>

Are you sure that you want to sign this key with your
key "Fwknop Client (client) <client@client.org>" (0xFFE5312387B46932)

Really sign? (y/N) y

You need a passphrase to unlock the secret key for
user: "Fwknop Client (client) <client@client.org>"
2048-bit RSA key, ID 0xFFE5312387B46932, created 2014-08-08

Musimy jeszcze skonfigurować dostęp do serwera. Edytujemy zatem plik /etc/fwknop/access.conf i uzupełniamy go do poniższej postaci:

SOURCE                     192.168.10.20
OPEN_PORTS                 tcp/22
REQUIRE_SOURCE_ADDRESS     Y
GPG_REMOTE_ID              0x72F3A416B820057A;
GPG_DECRYPT_ID             0xFFE5312387B46932;
GPG_DECRYPT_PW             test
#GPG_ALLOW_NO_PW              Y
HMAC_KEY_BASE64            /DzjyCA6arIzwzdc2Cwx5P2pj9N7yQ0eKLybadDWZfPJY5/xGgyFSjcdlzL3+oGrAYGZvKk/OrOo0ymKpGqgGg==
GPG_HOME_DIR               /root/.gnupg
FW_ACCESS_TIMEOUT          30

Jeśli chcemy mieć klucz bez hasła, ustawiamy opcję GPG_ALLOW_NO_PW .

Generujemy teraz plik ~/.fwknoprc na maszynie klienckiej:

$ fwknop -A tcp/22 --gpg-recipient-key 0x72F3A416B820057A --gpg-signer-key 0xFFE5312387B46932 -a 192.160.10.20 -D 192.168.1.150 --save-rc-stanza

Powinien zostać wygenerowany plik o poniższej zawartości:

[192.168.1.150]
ALLOW_IP                    192.160.10.20
USE_GPG                     Y
GPG_RECIPIENT               0x72F3A416B820057A
GPG_SIGNER                  0xFFE5312387B46932
ACCESS                      tcp/22
SPA_SERVER                  192.168.1.150

Jednak te ustawienia nie dadzą nam przepustki. Dodatkowo potrzebne nam są dwa parametry KEY_BASE64 oraz HMAC_KEY_BASE64 w formie:

KEY_BASE64              a29rc2lr
HMAC_KEY_BASE64             /DzjyCA6arIzwzdc2Cwx5P2pj9N7yQ0eKLybadDWZfPJY5/xGgyFSjcdlzL3+oGrAYGZvKk/OrOo0ymKpG
qgGg==

KEY_BASE64 określa hasło do klucza na maszynie klienckiej zakodowane w base64. By taki ciąg stworzyć wpisujemy w terminalu poniższą linijkę:

echo -n "jakies tam haslo" | base64

Hasło można również określić zwykłym tekstem zastępując parametr KEY_BASE64 przy pomocy KEY . Można także usunąć zupełnie te opcję z pliku i wtedy będzie trzeba podawać hasło w terminalu za każdym razem podczas otwierania portu na serwerze.

Jeśli chodzi o drugi z powyższych parametrów -- HMAC_KEY_BASE64 , można go wygenerować przy pomocy poniższej linijki:

$ fwknop --key-gen --use-hmac
...
HMAC_KEY_BASE64: 3Q+Dsk1BJbmUVrSdxcgmzZTiNer34d4hbSyI/xI5LCu9c+7N4grq9G+4mWAzKOA8+SLUw3NTVNu6WscrhiAhxw==

Przy czym trzeba pamiętać by odpowiednio uzupełnić plik /etc/fwknop/access.conf na serwerze.

Od tej pory by wysłać ciasteczko do serwera i otworzyć tym samym port, wpisujemy:

$ fwknop -n 192.168.1.150

I można się logować na ssh.

Pisane na podstawie:
http://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html#fwknop-gpg .

OSnews Wykop Blip Flaker Kciuk Śledzik Facebook Identi.ca Twitter del.icio.us Google Bookmarks