- PagerDuty /
- Der Blog /
- Sicherheit /
- Definieren und Verteilen von Sicherheitsprotokollen zur Fehlertoleranz
Der Blog
Definieren und Verteilen von Sicherheitsprotokollen zur Fehlertoleranz
Dies ist der zweite Beitrag in einer Reihe darüber, wie wir die Sicherheit bei PagerDuty verwalten. Um von Anfang an zu beginnen, schauen Sie sich an: So stellen wir sicher, dass PagerDuty für unsere Kunden sicher ist .
Hohe Verfügbarkeit und Zuverlässigkeit sind hier bei PagerDuty äußerst wichtig. Wir haben enorm viel Zeit damit verbracht, unseren Dienst so zu gestalten, dass er Ausfällen auf Servern, in Rechenzentren, Regionen, bei Anbietern, externen Abhängigkeiten und vielen anderen Faktoren standhält. Aber wie bauen Sie angesichts der Tatsache, dass Ausfälle unvermeidlich sind, Fehlertoleranz in unser Sicherheitssystem ein?
Zwei Dinge sollten Sie dabei bedenken: Erstens bringt dedizierte Netzwerk- oder Sicherheitshardware das Problem einzelner Ausfallpunkte mit sich, wenn beispielsweise ein VPN-Gerät ausfällt und ein ganzes Rechenzentrum lahmlegen kann. Zweitens erhält ein Angreifer in einem Sicherheitsmodell, bei dem nur der Rand des Netzwerks geschützt ist, wenn er diese einzelne Schicht durchdringen kann, Zugriff auf alles.
Um diese Probleme zu vermeiden, besteht unser Ansatz darin, unsere Sicherheitsrichtlinien zentral zu verwalten und die Durchsetzung auf alle Knoten zu übertragen. Jeder Knoten ist dafür verantwortlich, die Richtliniendefinitionen nachzuschlagen sowie einen maßgeschneiderten Regelsatz abzuleiten und durchzusetzen.
Dynamisch berechnete lokale Firewalls
Die erste Strategie, die wir in unserem zentralisierten Verwaltungs-/verteilten Durchsetzungsmodell implementiert haben, waren unsere dynamischen Firewalls.
Wir haben PagerDuty in den letzten zwei Jahren auf eine serviceorientierte Architektur migriert und haben damit die Möglichkeit, jeden Dienst besser zu isolieren und laterale Bewegungen einzudämmen. Wenn wir in Chef einen neuen Servercluster definieren, richten wir auch den Regelsatz für die Firewalls ein, der definiert, zu welcher Gruppe dieser Server gehört und welche Gruppen mit dieser Gruppe kommunizieren können. Dadurch kann jeder Server automatisch ganze IPTables-Ketten erstellen, Service-Ports für die entsprechenden Quellen öffnen und allen anderen Datenverkehr löschen. Das bedeutet, dass wir jedes Mal, wenn ein Server hinzugefügt/entfernt wird, keine Richtlinien aktualisieren müssen. Stattdessen erkennen die Knoten die Änderung und berechnen den Regelsatz neu.
Dieser Ansatz bietet uns eine Reihe von Vorteilen:
-
Bei Bedarf können wir problemlos Netzwerkpartitionen erstellen. (So stellen wir sicher, dass unsere Entwicklungs-, Test- und Produktionsumgebungen nicht miteinander kommunizieren können.)
-
Wir können einzelne Server isolieren, wenn wir Angriffe auf sie üben müssen.
-
Wir können leicht herausfinden, welche Server miteinander kommunizieren, da alle eingehenden Regeln im Voraus definiert werden müssen.
-
Wir verwenden einfache und unkomplizierte Linux IPTables. Wenn es ein Firewall-Problem gibt, weiß jeder Techniker, wie man die Firewall manipuliert und eine Lösung bereitstellt.
-
Es gibt kein Netzwerkgerät, das als Single Point of Failure gilt. Wenn ein einzelner Server ausfällt oder etwas noch Katastrophales passiert, läuft der Rest des Systems weiterhin sicher weiter.
Verteilte Datenverkehrsverschlüsselung
Für die Verschlüsselung des Netzwerkverkehrs werden vor allem zwei Methoden verwendet: Virtuelle private Netzwerke (VPN) und Verschlüsselung pro App/Dienst. Bei beiden haben wir jedoch Probleme festgestellt.
Eine typische VPN-Implementierung mit dedizierten Gateways in jeder unserer AWS- und Linode-Regionen hätte eine Reihe von Problemen mit sich gebracht:
-
Fast ein einziger Ausfallpunkt. Selbst wenn Sie in jeder Region mehrere Gateways bereitstellen, kommt es bei jedem Ausfall eines Gateway-Servers entweder zu einem Failover oder zu einer Kapazitätsreduzierung. Dies führt zu Verbindungsproblemen.
-
Kosten und Skalierbarkeit. Da wir standardmäßige virtuelle Maschinen und keine dedizierte Netzwerkhardware verwenden, müssten wir sehr große Instanzgrößen verwenden, um den Datenverkehr für die dahinter liegenden Server zu verschlüsseln und zu entschlüsseln. Wir waren besorgt über die Fähigkeit herkömmlicher VPN-Gateways, mit unseren Datenverkehrsspitzen zu skalieren.
-
Latenz. Da wir bereits über regionenübergreifende Anrufe verfügen, möchten wir bei der Verbindung mit nicht lokalen Servern so wenig Hops wie möglich.
Verschlüsselungsmethoden pro App/Dienst – wie MySQL dazu zu zwingen, nur SSL-Verbindungen zuzulassen oder sicherzustellen, dass Cassandra Interknoten-Verschlüsselung verwendet – haben in unserem Sicherheitsrahmen durchaus ihren Platz. Aber es gibt Probleme, wenn man nur diesen Ansatz verwendet:
-
Das vergisst man leicht. Obwohl Sicherheit Teil der Arbeit eines jeden in einem Unternehmen ist, wird oft vergessen, die entsprechenden Sicherheitseinstellungen zu aktivieren.
-
Jede App/jeder Dienst verschlüsselt Daten auf eine etwas andere Weise. Obwohl die meisten Verbindungsbibliotheken SSL unterstützen, kann es jedes Mal anders implementiert werden. Darüber hinaus bedeutet dies, dass wir jedes Mal, wenn wir einen neuen Dienst hinzufügen, neu darüber nachdenken müssen, wie wir mit der Verschlüsselung umgehen.
Um die oben genannten Probleme zu lösen, haben wir ein Punkt-zu-Punkt-Verschlüsselungsmodell auf Basis von IPSec im Transportmodus implementiert. Dadurch kann der gesamte Datenverkehr zwischen bestimmten Knoten im Netzwerk verschlüsselt werden, unabhängig davon, wo sich der Knoten befindet und mit welchen anderen Knoten er kommuniziert. Auch hier sind wir unserer Konvention zur zentralisierten Richtlinienverwaltung gefolgt, indem wir die Beziehungen auf einem Chef-Server berechnet und sie dann an jeden Knoten weitergegeben haben.
Die Verwendung der Punkt-zu-Punkt-Verschlüsselung gegenüber dem herkömmlichen VPN-Modell bietet mehrere Vorteile:
-
Dezentrale Verschlüsselung. Anstatt sich auf kritische VPN-Gateways zu verlassen, kann jeder Knoten seine eigene Verschlüsselung handhaben (Entfernung einzelner Ausfallpunkte).
-
Skalierbarkeit. Da Beziehungen nur für die Knoten berechnet werden, mit denen ein einzelner Knoten kommunizieren muss (und nicht für jeden Knoten), ist der Aufwand der Verschlüsselung ziemlich gering. Bei unseren ersten Benchmarks stellten wir fest, dass die Leistung nachließ, wenn ein Knoten mit Tausenden von Knoten kommunizieren musste, aber solange unsere Dienste isoliert und in sich geschlossen bleiben, sollte dieses Modell für unsere Anforderungen skalierbar sein.
-
Effizienz. Wir können die dedizierte AES-Hardware nutzen, die mit den meisten modernen Chipsätzen geliefert wird. Da der Datenverkehr verschlüsselt und komprimiert wird, haben wir zudem nur eine Beeinträchtigung unseres Netzwerkdurchsatzes von 2-3 % festgestellt.
-
Verschlüsselung innerhalb des Rechenzentrums. Das Senden von Datenverkehr über dedizierte Verbindungen innerhalb oder zwischen Rechenzentren ist im Allgemeinen sicher, aber die jüngsten Ereignisse haben die Gefahr von Sicherheitslücken bei solchen Verbindungen aufkommen lassen. Die Punkt-zu-Punkt-Verschlüsselung bietet eine bessere Alternative.
-
Eine Abhängigkeit weniger von NAT. Da immer mehr Netzwerke IPv6 und einen globalen Adressraum unterstützen, muss der von VPNs bereitgestellte private Adressraum neu gestaltet werden. Unser Punkt-zu-Punkt-Modell unterstützt problemlos einen globalen Adressraum.
-
Vollständige End-to-End-Verschlüsselung. Switches, Router, Glasfaser-Taps, benachbarte Hosts, die Hosting-Anbieter selbst. Dies sind alles Beispiele für potenzielle Angriffsvektoren. Durch die durchgehende Verschlüsselung des Datenverkehrs könnte ein Eindringling, selbst wenn er unseren Datenverkehr abfangen könnte, nichts davon lesen.
Rollenbasierte Zugriffskontrolle
PagerDuty folgt einem Berechtigungsmodell mit den geringsten Berechtigungen. Im Grunde bedeutet dies, dass Ingenieure nur auf die Server zugreifen können, die sie für ihre Arbeit benötigen. Wir nutzen Chef in Verbindung mit einfachen Linux-Benutzern/-Gruppen, um unsere Zugriffskontrollen aufzubauen.
Wenn wir unserer Infrastruktur einen neuen Benutzer hinzufügen, müssen wir die Gruppen hinzufügen, zu denen dieser Benutzer gehört. Wenn wir eine neue Gruppe von Servern hinzufügen, müssen wir angeben, welche Benutzergruppen Zugriff auf diese Server haben. Mit diesen Informationen können wir die Passwd- und Gruppendateien auf jedem Host erstellen. Da dies alles in JSON-Konfigurationsdateien gespeichert und in der Versionskontrolle enthalten ist, ist es einfach, Zugriffsanforderungen/Genehmigungen in unseren Codeüberprüfungsprozess einzubinden.