So sichern Sie Consul mit TLS-Verschlüsselung unter Ubuntu 14.04

Einführung

Consul ist ein Diensterkennungstool, mit dem Sie auf einfache Weise den Zustand verschiedener Dienste in Ihrer gesamten Infrastruktur erkennen und verfolgen können. Mit consul können Sie Ihre Dienste verwalten und ein verteiltes Überprüfungssystem verwalten, um sicherzustellen, dass Sie reagieren können, wenn Anwendungen oder Server ausfallen.

Im last guide haben wir uns darauf konzentriert, eine Produktion zu erstellen -bereite Umgebung und fertig. Dies beinhaltete das Erstellen von Konfigurationsdateien, die beim Booten gelesen wurden, und das Starten von Skripts, um die Dienste tatsächlich zu initiieren.

Dies führte uns zum größten Teil zu unserer endgültigen Basiskonfiguration, aber wir haben unsere Konfiguration noch nicht vollständig gesichert. Wir haben eine einfache gemeinsame geheime Lösung implementiert, die unser Klatschprotokoll sehr einfach verschlüsselt.

Die RPC-Kommunikation ist zu diesem Zeitpunkt jedoch noch vollständig unverschlüsselt. Um dieses Problem zu lösen, unterstützt Consul native TLS-Verschlüsselung, auf die wir uns in diesem Handbuch konzentrieren werden. Um dies zu implementieren, müssen wir eine Zertifizierungsstelle erstellen und Schlüssel signieren und an unsere Knoten verteilen.

Voraussetzungen und Ziele

Bevor Sie dieses Handbuch fertigstellen, sollten Sie ein System von Consul-Servern einrichten, wie wir es in unserem letzten Handbuch unter https://www.digitalocean.com/community/tutorials/how-to-configure-consul-in-a angegeben haben -production-environment-on-ubuntu-14-04 [einrichtung einer produktionsfertigen consul-infrastruktur].

Die Server, die wir für dieses Handbuch hatten, hatten die folgenden Eigenschaften:

Hostname IP Address Role

server1.example.com

192.0.2.1

bootstrap consul server

server2.example.com

192.0.2.2

consul server

server3.example.com

192.0.2.3

consul server

agent1.example.com

192.0.2.50

consul client

Dies sind 64-Bit-Ubuntu 14.04-Server. Bitte beachten Sie, dass sich jeder dieser Server in derselben Domain befindet. Dies ist wichtig für die Konfiguration, die wir in diesem Handbuch implementieren, da wir ein Platzhalterzertifikat verwenden, das für jeden der Hosts in der Domäne geeignet ist.

In diesem Handbuch konzentrieren wir uns auf die Erstellung einer TLS-Zertifizierungsstelle, um Zertifikate für jeden unserer Server zu signieren. Auf diese Weise können die Konsul-Komponenten Identitäten überprüfen und den Datenverkehr verschlüsseln. Wir werden dann die Konfigurationsdateien leicht modifizieren, um unsere Knoten zu zwingen, den Datenverkehr zu verschlüsseln.

Erstellen Sie die SSL-Struktur

Zunächst richten wir einige grundlegende Dateien und Verzeichnisse ein, mit denen wir unsere Schlüssel verwalten.

Auch hier werden wir alle Verfahren in diesem Handbuch in einer Root-Shell ausführen. Melden Sie sich entweder als root an oder verwenden Sie "+ sudo -i +" als Benutzer mit sudo-Berechtigungen.

Erstellen Sie auf jedem Ihrer Konsul-Mitglieder ein Verzeichnis "+ ssl " im Verzeichnis " / etc / consul.d +". Hier speichern wir die erforderlichen Dateien für die Verschlüsselung des RPC-Verkehrs:

mkdir /etc/consul.d/ssl

Auf dem Server, den Sie als Zertifizierungsstelle verwenden möchten, erstellen wir ein Unterverzeichnis in diesem Verzeichnis, in dem alle zum Erstellen und Signieren der Zertifikate erforderlichen Dateien gespeichert werden. Wir können jeden unserer Server auswählen, auf dem sich die Zertifizierungsstelle befindet. Für unsere Zwecke verwenden wir jedoch "+ server1 +", auf dem sich auch die Bootstrap-Konfiguration befindet.

Erstellen Sie auf diesem Server ein Unterverzeichnis mit dem Namen "+ CA +" unter dem soeben erstellten Verzeichnis:

mkdir /etc/consul.d/ssl/CA

Dies wird einige vertrauliche Daten enthalten, auf die andere Personen wahrscheinlich nicht zugreifen sollen. Lassen Sie uns also die Berechtigungen sperren:

chmod 0700 /etc/consul.d/ssl/CA

Verschieben Sie in dieses Verzeichnis auf dem CA-Server.

cd /etc/consul.d/ssl/CA

Hier erstellen wir einige grundlegende Dateien, die für unsere Zertifikatsignierung vorhanden sein müssen. Zuerst müssen wir eine Datei erstellen, die mit der nächsten verfügbaren Seriennummer für Zertifikate inkrementiert wird. Wir müssen dies mit einem Wert voreinstellen.

Geben Sie dazu den Wert "+ 000a +" in die serielle Datei ein:

echo "000a" > serial

Wir müssen auch eine Datei bereitstellen, in der unsere Zertifizierungsstelle die von ihr signierten Zertifikate aufzeichnen kann. Wir werden diese Datei "+ certindex +" nennen:

touch certindex

Erstellen Sie ein selbstsigniertes Stammzertifikat

Um mit unserer Zertifizierungsstelle zu beginnen, müssen wir zunächst ein selbstsigniertes Stammzertifikat erstellen. Wir können das mit dem Befehl + openssl + machen, der standardmäßig auf Ubuntu-Rechnern installiert ist.

Der Befehl, den wir zum Erstellen des Zertifikats verwenden, lautet:

openssl req -x509 -newkey rsa:2048 -days 3650 -nodes -out ca.cert

Lassen Sie uns noch einmal überlegen, was dies bedeutet:

  • * req *: Dieses Argument teilt openssl mit, dass Sie daran interessiert sind, ein PKCS#10 -Zertifikat zu bearbeiten, indem Sie Anforderungen erstellen oder verarbeiten.

  • * -x509 *: Dieses Argument gibt an, dass Sie ein selbstsigniertes Zertifikat anstelle einer Zertifikatanforderung wünschen. Dies wird normalerweise für Stammzertifizierungsstellenzertifikate durchgeführt.

  • * -newkey rsa: 2048 *: Hiermit wird openssl angewiesen, eine neue Zertifikatsanforderung und einen neuen privaten Schlüssel zu generieren. Wir übergeben ihm ein Argument, das angibt, dass wir einen RSA-Schlüssel mit 2048 Bit wollen.

  • * -days 3650 *: Hier geben wir die Anzahl der Tage an, an denen das Zertifikat als gültig angesehen wird. Wir verwenden einen Wert von "+ 3650 +", was 10 Jahren entspricht.

  • * -nodes *: Dies gibt an, dass der generierte private Schlüssel nicht mit DES verschlüsselt wird, wofür ein Passwort erforderlich wäre. Dies vermeidet diese Anforderung.

  • * -out ca.cert *: Legt den Dateinamen fest, der für die generierte Zertifikatdatei verwendet wird.

Während der Zertifikaterstellung werden Sie aufgefordert, Informationen zu dem Host einzugeben, den Sie zertifizieren. Sie können dies mit allen relevanten Informationen ausfüllen, die Sie über den Server wünschen:

. . .
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:ConsulCA
Email Address []:[email protected]

Für den "+ Common Name +", der in unserem anderen Zertifikat wichtig sein wird, können Sie angeben, was Sie möchten.

Wenn Sie fertig sind, sollten Sie eine "+ ca.cert " - Zertifikatsdatei sowie einen zugehörigen Schlüssel mit dem Namen " privkey.pem +" haben.

Erstellen Sie eine Platzhalterzertifikatsignierungsanforderung

Nachdem wir das Stammzertifizierungsstellenzertifikat haben, können wir eine Zertifikatsignierungsanforderung für unsere Clientcomputer generieren.

In diesem Fall sind alle unsere Konsul-Mitglieder Kunden, einschließlich des Servers, auf dem wir gerade arbeiten. Anstatt für jeden Server ein eindeutiges Zertifikat zu generieren und es bei unserer Zertifizierungsstelle zu signieren, erstellen wir ein Platzhalterzertifikat, das für jeden der Hosts in unserer Domäne gültig ist.

Das allgemeine Format des Befehls ist mit ein paar kleinen Unterschieden identisch:

openssl req -newkey rsa:1024 -nodes -out consul.csr -keyout consul.key

Der Unterschied zwischen der selbstsignierten Zertifikatanforderung der Stammzertifizierungsstelle, die wir erstellt haben, und der neuen Zertifikatsignierungsanforderung, die wir gerade generieren, ist folgender:

  • * no -x509 flag *: Wir haben das + -x509 + Flag entfernt, um eine Zertifikatsignierungsanforderung anstelle eines selbstsignierten Zertifikats zu generieren.

  • * -out consul.csr *: Die ausgegebene Datei ist kein Zertifikat selbst, sondern eine Zertifikatsignierungsanforderung.

  • * -keyout consul.key *: Wir haben den Namen des Schlüssels angegeben, der der Zertifikatsignierungsanforderung zugeordnet ist.

Auch hier werden wir zur Beantwortung der Certificate Signing Request (CSR) aufgefordert. Dies ist wichtiger als die Antworten, die wir für das selbstsignierte Stammzertifizierungsstellenzertifikat angegeben haben. Hier müssen wir einen Platzhalter "+ Common Name" verwenden, damit Ihr Zertifikat für jeden unserer Hosts als gültig gilt:

. . .
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:[email protected]

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Wie Sie hier sehen können, haben wir unsere Domain mit einem Stern als Host verwendet, um anzuzeigen, dass das Zertifikat für jeden Host innerhalb der Domain als gültig angesehen werden soll. Sie können das Abfragekennwort und die optionalen Eingabeaufforderungen für Firmennamen, die am Ende hinzugefügt werden, problemlos überspringen.

Erstellen Sie eine Zertifizierungsstellenkonfigurationsdatei

Jetzt haben wir unsere selbstsignierte Stammzertifizierungsstellendatei und eine Platzhalterzertifizierungsanforderung, die allen Hosts in unserer Domain entspricht. Bevor wir die Signaturanforderung mit unserem CA-Zertifikat signieren können, müssen wir eine Konfigurationsdatei erstellen, die steuert, wie dies geschieht.

Wir rufen die Datei auf, die wir erstellen: "+ myca.conf +", die unsere CA-Informationen enthält. Öffnen Sie diese Datei jetzt:

nano /etc/consul.d/ssl/CA/myca.conf

Diese Datei verwendet ein INI-Format, das in Abschnitte unterteilt ist. Der erste Abschnitt, den wir definieren werden, ist der Abschnitt "+ ca +". Das einzige, was wir hier tun werden, ist auf unseren benutzerdefinierten Abschnitt mit den tatsächlichen CA-Informationen zu verweisen:

[ ca ]
default_ca = myca

Als Nächstes erstellen wir den Abschnitt, auf den wir gerade verwiesen haben. Dies enthält den Großteil der CA-Konfigurationsdetails.

Wir werden angeben, dass die in die Sicherheitsabfragen eingegebenen Informationen nicht eindeutig sein müssen. Anschließend geben wir den Speicherort aller von uns erstellten Dateien an, die für den Signaturprozess benötigt werden. Wir werden + openssl + anweisen, neue Zertifikate im aktuellen Verzeichnis abzulegen.

Wir möchten auch einige Standardeinstellungen auswählen, die verwendet werden sollen, wenn in der Befehlszeile keine Alternativen angegeben sind. Wir werden die signierten Zertifikate 10 Jahre lang als gültig auswählen und den Algorithmus + sha1 + verwenden. Abschließend verweisen wir auf einige zusätzliche Abschnitte, die wir erstellen, um zusätzliche Informationen zu definieren:

[ myca ]
unique_subject = no
new_certs_dir = .
certificate = ca.cert
database = certindex
private_key = privkey.pem
serial = serial
default_days = 3650
default_md = sha1
policy = myca_policy
x509_extensions = myca_extensions

Konzentrieren wir uns nun auf den ersten benutzerdefinierten Abschnitt, auf den wir gerade verwiesen haben, in dem entschieden wird, welche Informationen bereitgestellt werden müssen, damit der CSR akzeptiert wird. Einige Felder werden als erforderlich und andere als optional gekennzeichnet. Wir werden einige ziemlich standardmäßige Entscheidungen für die üblichen Eingabeaufforderungen treffen:

[ myca_policy ]
commonName = supplied
stateOrProvinceName = supplied
countryName = supplied
emailAddress = optional
organizationName = supplied
organizationalUnitName = optional

Im letzten Abschnitt werden die x509-Erweiterungen definiert, die beim Signieren von Zertifikaten verwendet werden sollen.

Zunächst müssen wir darauf hinweisen, dass es sich bei dem zu signierenden Zertifikat nicht um ein CA-Zertifikat handelt. Wir werden den Standardwert von "Hash" für die Subjektschlüsselkennung verwenden, da hexadezimale Zeichenfolgen (die Alternative) dringend davon abgeraten werden.

Wir setzen die Kennung des Berechtigungsschlüssels auf "keyid", um die Kennung des Betreffschlüssels aus dem übergeordneten Zertifikat zu kopieren. Wir werden auch festlegen, dass die Schlüssel als Signatur oder mit einem Protokoll zum Verschlüsseln von Schlüsseln verwendet werden können. Wir werden angeben, dass die erweiterte Verwendung der Schlüssel für die Server- und Clientauthentifizierung erfolgen kann:

[ myca_extensions ]
basicConstraints = CA:false
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
keyUsage = digitalSignature,keyEncipherment
extendedKeyUsage = serverAuth,clientAuth

Insgesamt sieht die Datei ungefähr so ​​aus:

[ ca ]
default_ca = myca

[ myca ]
unique_subject = no
new_certs_dir = .
certificate = ca.cert
database = certindex
private_key = privkey.pem
serial = serial
default_days = 3650
default_md = sha1
policy = myca_policy
x509_extensions = myca_extensions

[ myca_policy ]
commonName = supplied
stateOrProvinceName = supplied
countryName = supplied
emailAddress = optional
organizationName = supplied
organizationalUnitName = optional

[ myca_extensions ]
basicConstraints = CA:false
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
keyUsage = digitalSignature,keyEncipherment
extendedKeyUsage = serverAuth,clientAuth

Speichern und schließen Sie die Datei, wenn Sie fertig sind. Wir haben jetzt eine umfangreiche Konfigurationsdatei, die zum Signieren der zuvor generierten Zertifikatsignierungsanforderung verwendet werden kann.

Signieren Sie die Zertifikatsignierungsanforderung, um ein Zertifikat zu generieren

Jetzt verfügen wir über alle Komponenten, die zum Signieren der CSR und zum Generieren eines Zertifikats erforderlich sind. Wir müssen nur auf die Konfigurationsdatei verweisen, die wir gerade erstellt haben, und die CSR übergeben, die wir generiert haben.

Der Befehl, den wir verwenden werden, ist:

openssl ca -batch -config myca.conf -notext -in consul.csr -out consul.cert

Wir verwenden folgende Optionen:

  • * ca *: Verwenden Sie die Verwaltungsfunktion von openssl für Zertifizierungsstellen.

  • * -batch *: Gibt an, dass der Batch-Modus aktiviert werden soll. Der Batch-Modus zertifiziert automatisch alle übergebenen CSRs, ohne dass Sie dazu aufgefordert werden.

  • * -config myca.conf *: Geben Sie die von uns erstellte Konfigurationsdatei ein.

  • * -notext *: Geben Sie die Textform des Zertifikats nicht aus.

Die restlichen Optionen geben die Eingabe- und Ausgabedateien an.

Dadurch wird eine Datei mit dem Namen "+ consul.cert " im aktuellen Verzeichnis erstellt. Außerdem werden neue Versionen der Dateien " serial " und " certindex " erstellt, wobei die alten Versionen in Sicherungsdateien verschoben werden. Eine ` .pem ` Datei wird ebenfalls basierend auf der Seriennummer in der ` serial +` Datei erstellt.

Verschieben Sie die Dateien an den richtigen Speicherort

Jetzt haben wir alle benötigten Komponenten im Verzeichnis "+ / etc / consul.d / ssl / CA ". Wir wollen die drei benötigten Dateien in das Verzeichnis " / etc / consul.d / ssl +" kopieren, wo wir sie referenzieren:

cp ca.cert consul.key consul.cert ..

Unser "+ server1 +" - Rechner, auf dem sich die Zertifizierungsstelle befindet, verfügt nun über die erforderlichen Zertifikats- und Schlüsseldateien am richtigen Speicherort.

Um sie auf die anderen Computer in Ihrer Infrastruktur zu übertragen, ist "+ scp " eine gute Wahl. Aus dem Verzeichnis " / etc / consul.d / ssl " auf " server1 +" können Sie die erforderlichen Dateien auf die anderen Server übertragen, indem Sie Folgendes eingeben:

cd /etc/consul.d/ssl
scp ca.cert consul.key consul.cert root@:/etc/consul.d/ssl
scp ca.cert consul.key consul.cert root@:/etc/consul.d/ssl
scp ca.cert consul.key consul.cert root@:/etc/consul.d/ssl

Ändern Sie die IP-Adressen, um auf alle Computer in Ihrer Infrastruktur zu verweisen.

Ändern Sie die Consul-Konfigurationsdateien

Nachdem wir nun unsere Stammzertifikatsdatei und ein Zertifikat / Schlüssel-Paar für unsere Konsul-Mitglieder haben, können wir unsere Konsul-Konfigurationsdateien so ändern, dass sie auf diese Dateien verweisen.

Öffnen Sie jede der consul-Konfigurationsdateien auf Ihren Servern. Für unsere + server1 + Maschine beginnen wir mit der Bootstrap-Konfigurationsdatei:

nano /etc/consul.d/bootstrap/config.json

Die Datei sollte momentan so aussehen:

{
   "bootstrap": true,
   "server": true,
   "datacenter": "nyc2",
   "data_dir": "/var/consul",
   "encrypt": "pmsKacTdVOb4x8/Vtr9PWw==",
   "log_level": "INFO",
   "enable_syslog": true
}

Als erstes sollten wir die consul-Parameter verwenden, um jede unserer neuen Dateien zu identifizieren. Der Parameter "+ ca_file " verweist auf den Speicherort der CA-Zertifikatdatei. Die Parameter " cert_file " und " key_file +" verweisen auf die Zertifikats- bzw. Schlüsseldateien des Clients.

Da dies auch mit der Verschlüsselung zu tun hat, werden wir sie aus Gründen der Übersichtlichkeit unter dem Parameter "+ encrypt +" einfügen:

{
   "bootstrap": true,
   "server": true,
   "datacenter": "nyc2",
   "data_dir": "/var/consul",
   "encrypt": "pmsKacTdVOb4x8/Vtr9PWw==",



   "log_level": "INFO",
   "enable_syslog": true
}

Jetzt haben wir die Speicherorte dieser Dateien definiert, aber wir haben consul nicht mitgeteilt, dass wir die Authentizität jedes Hosts anhand dieser Dateien überprüfen möchten. Wir können das jetzt tun, indem wir den Konsul auffordern, sowohl eingehende als auch ausgehende Verbindungen zu überprüfen:

{
   "bootstrap": true,
   "server": true,
   "datacenter": "nyc2",
   "data_dir": "/var/consul",
   "encrypt": "pmsKacTdVOb4x8/Vtr9PWw==",
   "ca_file": "/etc/consul.d/ssl/ca.cert",
   "cert_file": "/etc/consul.d/ssl/consul.cert",
   "key_file": "/etc/consul.d/ssl/consul.key",


   "log_level": "INFO",
   "enable_syslog": true
}

Speichern und schließen Sie die Datei, wenn Sie fertig sind.

Nehmen Sie die gleichen Änderungen an allen Konfigurationsdateien vor, die Ihre Konsul-Mitglieder verwenden.

Auf "+ server1 " müssen Sie diese Änderungen an " /etc/consul.d/bootstrap/config.json" und "+ /etc/consul.d/server/config.json +" vornehmen.

Auf Ihren anderen Servern müssen Sie lediglich "+ / etc / consul.d / server / config.json " ändern. Auf Ihren Client-Rechnern müssten Sie ` / etc / consul.d / client / config.json +` ändern.

Neustart der Server

Um unseren verschlüsselten Datenverkehr zu implementieren, müssen Sie die Konsulsitzung für jedes Ihrer Konsul-Mitglieder neu starten.

Halten Sie auf jedem Computer in Ihrer Infrastruktur kurz an und starten Sie consul erneut:

stop consul && sleep 5 && start consul

Dies stoppt den Prozess und startet ihn vorübergehend neu.

Wenn Sie dies bei jedem Ihrer Konsul-Mitglieder nacheinander tun, verwenden diese SSL, um den RPC-Verkehr zwischen ihnen zu verschlüsseln. Wenn nur einige von ihnen umgeschaltet werden, können kurzzeitig Kommunikationsprobleme auftreten, da ein Teil des Datenverkehrs als nicht verschlüsselt zurückgewiesen wird.

Wenn alle Mitglieder neu gestartet werden, sollte der RPC-Verkehr vollständig verschlüsselt sein.

Fazit

Zu diesem Zeitpunkt sollten Sie ein ziemlich sicheres Service-Discovery-System für Ihre Infrastruktur eingerichtet haben. Wir haben alle systemeigenen Sicherheitssysteme genutzt, die mit consul verfügbar sind, um den Zugriff zu sperren und das Fälschen unserer verschiedenen Maschinen zu verhindern.