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ń: 7554
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 .