Selon le Data Breach Investigations Report de Verizon, plus de 50 % des intrusions qui ont eu lieu en 2021 ont pour origine une fuite d’identifiants de sécurité. Même en appliquant les meilleures recommandations de sécurité, un accès SSH sera toujours un risque de sécurité pour une infrastructure. Cet article entend démontrer pourquoi les contrôles d’accès par défaut de Linux ne sont pas suffisants pour mettre en place un accès SSH granulaire. EBPF sera exploré comme une potentielle solution pour surveiller et protéger un accès SSH.
1. Qu’est-ce qu’un accès SSH ?
Secure Shell (SSH) [1] est un protocole réseau permettant à un utilisateur de se connecter de façon sécurisée à une infrastructure à travers un réseau non sécurisé. Dans une entreprise, de nombreux acteurs ont habituellement besoin d’un accès SSH :
- les développeurs utilisent SSH pour déboguer leurs services dans les environnements de test, et parfois de production ;
- les équipes d’ingénierie de la fiabilité des sites (« Site Reliability Engineering » ou SRE dans la suite de l’article) et les administrateurs système utilisent leurs accès SSH pour effectuer des opérations de maintenance ou de configuration système ;
- les administrateurs de sécurité ont généralement besoin d’un accès SSH pour leurs investigations de sécurité ou pour une réponse à incident.
En théorie, le principe de moindre privilège doit être appliqué. Ce principe dit que chaque acteur doit avoir le plus petit accès suffisant pour effectuer les tâches dont il est chargé. Par exemple, les équipes SRE ou les administrateurs de sécurité auront probablement besoin d’un accès privilégié aux machines d’une infrastructure. Inversement, les équipes de développeurs n’en auront pas toujours besoin. Indépendamment de la question du niveau d’accès, les développeurs ne devraient avoir accès qu’aux machines qui exécutent les services dont ils sont responsables. Il s’agit donc aussi d’essayer de réduire le nombre d’acteurs ayant accès à toute l’infrastructure.
Malheureusement, ce principe est très difficile à appliquer. Dans un premier temps, déboguer un service implique souvent l’utilisation d’outils de surveillance d’application à l’exécution (tel que « ext4dist » [2] s’il était nécessaire d’analyser la distribution de la latence des opérations sur système de fichiers ext4). Or ces outils d’analyse de performances ont très souvent besoin d’un accès privilégié sur la machine, ce qui signifie que certains développeurs vont demander un accès privilégié temporaire ou même parfois permanent. De plus, avec l’adoption croissante des solutions d’orchestration de conteneurs comme Kubernetes, les machines d’une infrastructure ne sont plus nécessairement dédiées à des services prédéterminés. En effet, Kubernetes peut être configuré pour optimiser les ressources d’une infrastructure, et ainsi maximiser l’utilisation de chaque machine en lui demandant d’exécuter simultanément plusieurs services qui auraient été, auparavant, isolés. Ainsi, un accès privilégié sur l’une de ces machines pourrait donner à un développeur accès à des services dont il n’est pas directement responsable.
Au fur et à mesure de la croissance des équipes techniques d’une entreprise, le nombre d’utilisateurs privilégiés va ainsi augmenter, et la gestion des accès SSH va rapidement devenir un cauchemar pour les équipes de sécurité. Parallèlement, le risque de fuite d’un identifiant de sécurité explose.
2. Sécurisation d’un accès SSH
2.1 État de l’art et recommandations
Il est généralement accepté que l’utilisation d’un mécanisme d’authentification reposant sur une cryptographie asymétrique apporte un bien meilleur niveau de sécurité que l’utilisation de mots de passe [3]. C’est la raison pour laquelle il est préférable d’utiliser, pour chaque utilisateur, un jeu de clé privée/clé publique (appelées clés SSH dans la suite de l’article) unique au lieu d’un mot de passe. Néanmoins, cette méthode d’authentification introduit un problème logistique de taille : la gestion des clés SSH. En effet, une équipe de sécurité devra trouver une solution à 3 problèmes :
- la suppression et l’ajout de nouvelles clés SSH ;
- la rotation des clés SSH ;
- le passage à l’échelle en termes de personnel et d’infrastructure.
En clair, cette solution n’est gérable qu’à très petite échelle, et introduit de nombreux risques de fiabilité s’il fallait modifier et redéployer régulièrement toutes les configurations SSH de toutes les machines d’une infrastructure. C’est la raison pour laquelle la première recommandation pour sécuriser un accès SSH est d’utiliser des certificats et une autorité de certification (« Certificate Authority » ou CA dans la suite de l’article). Au lieu d’utiliser des clés uniques avec un accès sans expiration, des certificats temporaires sont délivrés par la CA pour que les clients SSH puissent s’authentifier auprès des machines de l’infrastructure, et que les machines de l’infrastructure puissent s’authentifier auprès des clients SSH. La gestion des accès SSH est donc déléguée à la CA, ce qui permettra d’ajouter, modifier ou supprimer des utilisateurs sans avoir besoin de changer la configuration de chaque machine individuellement.
La seconde recommandation de sécurité est d’utiliser une machine « bastion ». Une machine « bastion » a pour rôle d’être la seule machine d’une infrastructure dont le serveur SSH est accessible depuis le monde extérieur. Autrement dit, une machine « bastion » permet d’éviter d’exposer toutes les machines d’une infrastructure à Internet, et donc de réduire considérablement la surface d’attaque de l’entreprise. Cela permet également de centraliser les points d’entrée dans l’infrastructure, facilitant la surveillance et l’audit des connexions SSH. Similairement, il faut aussi configurer les pare-feux de toutes les machines de l’infrastructure pour n’accepter les connexions SSH que depuis la machine « bastion ».
La troisième recommandation de sécurité consiste à utiliser un mécanisme d’authentification à multiples facteurs (« Multi-Factor authentification » ou MFA dans la suite de l’article, aussi parfois appelé « 2-Factor Authentification » ou 2FA). L’objectif d’une MFA est de réduire le risque de fuite d’identifiants en demandant une validation par deux mécanismes d’authentification fondamentalement différents avant d’autoriser une connexion. Il existe de très nombreuses implémentations de MFA : une clé physique avec laquelle il faut interagir pour autoriser une connexion (comme une Google Titan ou une Yubikey), un SMS, un mot de passe à usage unique (« One-Time Password » ou OTP dans la suite de l’article) qui a une expiration dans le temps et qui est habituellement généré par une application (comme Google Authenticator ou Duo), etc. Ubuntu a d’ailleurs publié un guide très complet sur la configuration d’OpenSSH avec Google Authenticator dans le but d’aider les administrateurs de sécurité à mettre en place une MFA fiable rapidement [4].
La dernière recommandation de sécurité est d’activer, d’archiver et d’analyser en temps réel les logs de connexions aux différents serveurs SSH. Ces logs d’audit seront particulièrement importants en cas de fuite d’identifiants afin de lister les machines qui ont été compromises.
2.2 Pourquoi faut-il aller plus loin ?
2.2.1 Réduire le risque d’une fuite d’identifiants ne diminue pas son impact
Le principal objectif des recommandations présentées dans la partie précédente est de réduire le risque de fuite d’identifiants de connexion. En effet, l’utilisation de certificats et d’une méthode MFA permet de s’assurer qu’un accès est accordé temporairement et qu’il sera difficile de le compromettre. Malheureusement, même si cela diminue la probabilité qu’un accès soit compromis, cela n’affecte en aucun cas l’impact d’une fuite d’identifiants. Les nombreuses intrusions dont nous allons parler dans la suite de l’article attestent que le risque est encore bien réel, et que le facteur humain fait qu’il ne sera probablement jamais possible de dire avec certitude qu’un accès SSH ne peut pas être compromis.
Prenons par exemple la recommandation de sécurité au niveau de l’authentification à multiples facteurs. Toutes les implémentations de MFA ne se valent pas, en témoigne ce qui est arrivé à Jack Dorsey (PDG de Twitter) en 2019 [5]. En effet, Jack Dorsey a été victime d’une attaque de type « SIM swap » [6], permettant à un pirate de prendre le contrôle de son compte Twitter. Cet exemple est loin d’être un exemple isolé, comme le montre une publication du Federal Bureau of Investigation (FBI) [7] qui sonne l’alerte sur la multiplication des attaques de ce genre aux États-Unis. Lorsque l’implémentation d’une MFA repose sur l’utilisation d’un SMS, tout le modèle de sécurité repose sur l’opérateur téléphonique et sur la garantie que personne d’autre que le propriétaire du numéro de téléphone ne peut recevoir les SMS qui lui sont destinés. Cette implémentation introduit donc un nouveau point d’attaque qui est complètement hors du contrôle d’un administrateur de sécurité. C’est la raison pour laquelle il est généralement recommandé de se reposer sur des implémentations de MFA fondées sur une clé physique, ou, à défaut, une application capable de générer des mots de passe à usage unique. Notez, au passage, que même les clés physiques ne font pas exception à la règle : de nombreuses vulnérabilités ont été découvertes ces dernières années sur certains modèles, permettant à un attaquant d’extraire les clés de chiffrement [8], et même de contourner la vérification MFA entièrement [9]. Quoi qu’il en soit, une authentification à multiples facteurs reste une couche de sécurité primordiale pour protéger l’accès SSH à une infrastructure.
2.2.2 Un accès SSH est rarement granulaire
Ce sujet a déjà été évoqué dans la première partie de l’article : le nombre d’utilisateurs privilégiés d’une infrastructure est difficile à contenir parce que les accès SSH ne sont pas assez granulaires. Par exemple, des développeurs se retrouvent souvent avec des accès privilégiés permanents simplement pour pouvoir exécuter des outils d’analyse de performances. De même, les orchestrateurs de conteneurs floutent les limites entre les services, donnant ainsi un accès beaucoup plus large que nécessaire à de nombreux clients SSH. L’absence de granularité dans la distribution des accès explique l’ampleur des dégâts lors de la fuite d’identifiants de connexion. L’intrusion de sécurité dont GoDaddy a été victime en 2019 [10] est probablement le meilleur exemple d’une rapide escalade suite à la compromission d’un utilisateur privilégié. En résumé, un attaquant a mis la main sur les identifiants de connexion d’un utilisateur privilégié, menant à la compromission des infrastructures de près de 28 000 clients.
À la défense des administrateurs de sécurité, Linux ne rend pas les choses particulièrement simples lorsqu’il s’agit de configurer un accès granulaire à grande échelle. En effet, il serait possible d’utiliser les « Kernel capabilities » [11] ou le mode « setuid » [12] pour permettre à un utilisateur d’exécuter des tâches demandant un haut niveau d’accès, mais l’utilisation et le déploiement de ces configurations sont un véritable cauchemar logistique. En effet, cela impliquerait que pour chaque nouvel outil, ou pour chaque nouvel utilisateur, il faudrait redéployer une nouvelle configuration via un outil comme Chef [13] ou Ansible [14]. La complexité d’une telle solution forcera éventuellement de nombreux utilisateurs à demander un accès privilégié temporaire, voire même permanent.
2.2.3 L’audit des sessions SSH se limite aux événements de connexion et de déconnexion
La majorité des serveurs SSH ont la capacité d’exporter des logs d’audits. Malheureusement, ceux-ci se limitent généralement aux événements de connexion et de déconnexion d’un utilisateur. Bien que très utiles pour évaluer les machines explorées par un utilisateur compromis, cela ne suffit pas pour comprendre réellement ce qui a été fait sur chaque machine. Les équipes de sécurité auront donc besoin de déployer des outils de surveillance additionnels pour reconstituer la session SSH d’un utilisateur compromis. En fonction de l’intégration de ces solutions aux différents serveurs SSH utilisés dans une infrastructure, commencera alors un travail de chat et de souris pour isoler précisément l’activité de l’attaquant. Ce travail est fastidieux et fera perdre un temps précieux à une équipe de réponse à incident.
3. ssh-probe : vers une nouvelle génération de protection à l’exécution
La suite de l’article propose de s’intéresser à « ssh-probe » [15], un outil en sources libres et fondé sur eBPF dont l’objectif est de donner une visibilité en temps réel sur les sessions SSH actives d’une infrastructure. Dans un premier temps, nous allons montrer comment eBPF peut être utilisé pour surveiller une session SSH à l’exécution. Ensuite, nous présenterons comment « ssh-probe » introduit un nouveau contrôle d’accès granulaire qui permet de répondre aux besoins évoqués dans les parties précédentes. Enfin, nous discuterons des limites de « ssh-probe » et des futurs développements du projet.
« ssh-probe » a été développé pour fonctionner avec OpenSSH [16] puisque ce projet est également en sources libres et qu’il est l’une des implémentations de SSH les plus répandues aujourd’hui.
3.1 Surveillance des sessions SSH en temps réel
Extended Berkeley Packet Filter (eBPF) est un sous-système du noyau Linux qui permet d’exécuter du code dans une sandbox [17] en espace noyau. Cette technologie est principalement utilisée pour écrire des outils d’analyse de performances à l’exécution. Il existe de nombreux types de programmes eBPF [18] : certains sont dédiés au filtrage réseau, d’autres sont utilisés pour tracer certains événements du noyau (tels que les programmes « kprobe » [19] ou « tracepoint » [20]), etc. Un de ces types de programmes eBPF est dédié à tracer l’exécution des symboles exportés dans un binaire en espace utilisateur. Autrement dit, ce type de programme peut être utilisé pour exécuter du code dès qu’une fonction spécifique est appelée dans un programme en espace utilisateur. Ce type de programme s’appelle une « uprobe » et donne accès, entre autres, aux arguments donnés à la fonction au moment de son appel.
Dans notre cas, le serveur OpenSSH exporte un symbole nommé « setlogin » qui est appelé à la création d’une connexion avec le nom de l’utilisateur qui vient de se connecter. Cela signifie qu’en ajoutant une « uprobe » sur le symbole « setlogin » de OpenSSH, « ssh-probe » est capable de détecter lorsqu’un utilisateur se connecte et peut ainsi marquer le premier processus de cette session SSH. Lorsqu’une nouvelle session SSH est détectée, « ssh-probe » génère un identifiant aléatoire unique pour cette session, et marque tous les processus de la session avec cet identifiant. Pour cela, nous avons attaché de nombreux programmes eBPF à toutes les étapes du cycle de vie des processus, de sorte que « ssh-probe » puisse faire hériter l’appartenance à une session SSH d’un processus père à son processus fils.
Ensuite, grâce à près de 127 programmes eBPF ajoutés dans le noyau par « ssh-probe », nous sommes capables de suivre une session SSH pour comprendre précisément ce qu’un utilisateur est en train de faire. En effet, « ssh-probe » est en mesure de capturer :
- les événements relatifs à l’exécution de processus ;
- le changement d’identifiants et l’élévation de privilèges d’une session SSH : « ssh-probe » peut capturer le changement d’utilisateur, de groupe et même de « kernel capabilities ». Cette partie est importante pour comprendre exactement ce à quoi un utilisateur a accès durant la session ;
- les activités du système de fichiers : « ssh-probe » détecte quand des fichiers sensibles sont ouverts. Puisqu’il serait inutile de remonter la liste exhaustive de tous les fichiers ouverts lors d’une session SSH, il est possible de configurer « ssh-probe » pour ne s’intéresser qu’à certains fichiers ou dossiers ;
- la création de socket : « ssh-probe » surveille la création de socket pour détecter les tentatives d’accès au réseau ;
- une série d’événements noyaux considérés comme sensibles : ces événements sont généralement un indicateur qu’un utilisateur essaye de modifier le noyau (comme le chargement d’un nouveau module) ou de changer un paramètre qui pourrait avoir des implications de sécurité (comme le changement de la date et de l’heure du système par exemple) ;
- une série d’événements sur les processus considérés comme sensibles : « ssh-probe » est capable de détecter une série d’attaques connues qui sont généralement utilisées pour injecter du code ou extraire des données confidentielles ;
Tous ces événements sont collectés et analysés par « ssh-probe » qui peut ensuite les envoyer à un outil d’ingestion de logs comme Datadog, Splunk ou Elastic. Il est ensuite possible de reconstruire en temps réel les sessions SSH actives d’une infrastructure en regroupant les logs générés par « ssh-probe » selon leur identifiant de session.
3.2 Un nouveau contrôle d’accès
En plus de surveiller les sessions SSH, « ssh-probe » est capable de leur appliquer des profils de sécurité. Le profil de sécurité d’un utilisateur est la liste exhaustive de tout ce qu’il a le droit, ou non, de faire pendant une session SSH. Plus précisément, cette liste contient le comportement que « ssh-probe » doit surveiller pour évaluer l’exécution d’un binaire, l’accès à un fichier, la création d’une socket, etc. Autrement dit, pour toutes les catégories d’événements présentées dans la section précédente, un profil de sécurité définit si « ssh-probe » doit autoriser, ou non, l’accès à la ressource. Chaque entrée d’un profil peut être configurée avec l’une des actions suivantes :
- allow : indique à « ssh-probe » que l’accès à la ressource doit être autorisé, puis qu’un log d’audit doit être généré ;
- block : indique à « ssh-probe » que l’accès à la ressource doit être refusé, un log d’audit est ensuite généré. Dans la plupart des cas, « ssh-probe » interrompra l’exécution des appels système en lien avec la ressource bloquée grâce à la fonction bpf_override_return [21] ;
- mfa : indique à « ssh-probe » qu’une nouvelle vérification MFA doit être faite avant d’autoriser l’accès à la ressource ; cette vérification ne sera valable que pour la session en cours et seulement pour la ressource indiquée ;
- kill : indique à « ssh-probe » que la session SSH qui a tenté d’accéder à la ressource doit être tuée.
Il est également possible de configurer des actions par défaut pour chaque catégorie d’événements, dans le cas où l’opération détectée ne correspond à aucune des entrées du profil. Des exemples de profils sont disponibles sur le GitHub du projet [15].
Un aspect intéressant de ce nouveau contrôle d’accès est qu’il est implémenté au-dessus des contrôles d’accès normaux du noyau. Autrement dit, « ssh-probe » ne pourra pas donner accès à une ressource déjà refusée par l’un des contrôles d’accès du noyau. « ssh-probe » ne peut donc que restreindre davantage les accès donnés à une session SSH. Cette conception est particulièrement intéressante pour restreindre les droits donnés à une session SSH dont l’utilisateur est un « sudoer ». Un utilisateur « sudoer » est un utilisateur qui a le droit d’élever ses privilèges pour devenir l’utilisateur « root » de la machine. Les « sudoers » sont généralement listés dans le fichier /etc/sudoers ou dans le dossier /etc/sudoers.d/. Ainsi, même si un utilisateur élève ses privilèges pour devenir « root », « ssh-probe » sera capable d’appliquer le profil de sécurité de la session et donc de bloquer l’accès aux exécutables ou fichiers qui n’auraient pas été listés dans le profil de sécurité. Ainsi, un développeur qui serait « sudoer » parce qu’il a besoin d’exécuter des opérations privilégiées d’analyse de performances n’a aucune raison de tenter de lire ou de modifier le contenu de fichiers dans /root/.ssh/.
3.3 Limites et futurs développements pour « ssh-probe »
Même si une première version entièrement fonctionnelle de « ssh-probe » a été publiée l’année dernière, le projet est toujours en développement actif. En effet, eBPF continue d’être activement mis à jour dans le noyau, ce qui signifie que de nouveaux outils sont régulièrement ajoutés. Deux d’entre eux vont notamment être utilisés dans la prochaine version de « ssh-probe » :
- la fonction « bpf_send_signal » [22] : cette fonction a été ajoutée pour permettre à certains programmes eBPF d’émettre un signal au processus actif. « ssh-probe » l’utilisera notamment pour tuer de façon plus fiable une session SSH. En effet, aujourd’hui, « ssh-probe » tue le premier processus de la session SSH depuis son démon en espace utilisateur, et ensuite bloque tous les appels système exécutés par les processus de la session en cours d’exécution. Au lieu de bloquer les appels système, la fonction « bpf_send_signal » permettrait de s’assurer que tous les processus de la session sont tués au plus vite.
- « Kernel Runtime Security Instrumentation » (KRSI, aussi connu sous le nom de BPF « Linux Security Module ») [23] : cette récente addition dans le noyau permet d’utiliser des programmes eBPF pour implémenter un « Linux Security Module », l’interface privilégiée du noyau pour introduire un nouveau contrôle d’accès. Cette addition au noyau permet de formaliser l’utilisation d’eBPF pour introduire un contrôle d’accès robuste, évitant ainsi la multiplication des programmes sur tous les appels système.
De plus, il est important de noter que « ssh-probe » suit les sessions SSH grâce à la hiérarchie des processus. Cela signifie que toute opération qui permet d’exécuter un processus en dehors de l’arbre des processus d’une session SSH ne sera pas soumise au contrôle d’accès de « ssh-probe ». C’est par exemple le cas si un utilisateur démarre manuellement un conteneur, exécute un service « systemd » ou ajoute une tâche « cron ». Pour l’instant, il est recommandé de bloquer, dans tous les profils de sécurité, l’accès aux clients des orchestrateurs de conteneurs, ainsi que l’écriture dans des dossiers tels que /etc/crontab ou /etc/systemd/.
Enfin, « ssh-probe » ne s’occupe pas de la gestion de profils à grande échelle. Nous proposons de déléguer cette partie du projet à l’autorité de certification.
Conclusion
SSH est un service qui peut brutalement réduire à néant tous les efforts d’une équipe de sécurité pour protéger une infrastructure. La sécurisation des accès SSH est fondamentale pour garantir la sécurité d’une entreprise et des données de ses clients. Même si les recommandations de sécurité sur les accès SSH permettent de réduire considérablement le risque de fuite d’identifiants de connexion, elles n’ont aucun effet sur l’impact d’une compromission. Il est donc particulièrement important pour une équipe de sécurité d’utiliser un outil de surveillance à l’exécution pour obtenir de la visibilité sur les sessions SSH actives, et potentiellement limiter en temps réel ce qu’un utilisateur compromis pourra faire sur une infrastructure. « ssh-probe » montre comment eBPF peut être utilisé pour répondre à ce besoin.
Références
[1] IETF, « SSH protocol architecture », https://tools.ietf.org/html/rfc4251
[2] IOVisor, « Summarize ext4 operation latency distribution as a histogram », https://github.com/iovisor/bcc/blob/master/tools/ext4dist.py
[3] Marlon Dutra, « Scalable and secure access with SSH », https://engineering.fb.com/2016/09/12/security/scalable-and-secure-access-with-ssh
[4] Ubuntu, « Configure SSH to use two-factor authentication »,
https://ubuntu.com/tutorials/configure-ssh-2fa
[5] Brian Barrett, « How Twitter CEO Jack Dorsey’s Account Was Hacked »,
https://www.wired.com/story/jack-dorsey-twitter-hacked
[6] MITRE, « Sim card swap », https://attack.mitre.org/versions/v10/techniques/T1451/
[7] Federal Bureau of Investigation, « Criminals Increasing SIM Swap Schemes to Steal Millions of Dollars from US Public », https://www.ic3.gov/Media/Y2022/PSA220208
[8] Victor Lomne et Thomas Roche, « A side journey to Titan »,
https://ninjalab.io/wp-content/uploads/2021/01/a_side_journey_to_titan.pdf
[9] Andy Greenberg, « Chrome lets hackers phish even Unphishable Yubikey users », https://www.wired.com/story/chrome-yubikey-phishing-webusb
[10] Davey Winder, « GoDaddy Confirms Data Breach: What Customers Need To Know », https://www.forbes.com/sites/daveywinder/2020/05/05/godaddyconfirms-data-breach-what-19-million-customers-need-to-know
[11] Linux, « Kernel capabilities man pages », https://man7.org/linux/man-pages/man7/capabilities.7.html
[12] Jake Edge, « Calibre and setuid », https://lwn.net/Articles/465311
[13] Chef, « Secure Infrastructure Management Automation Tools »,
https://www.chef.io/products/chef-infrastructure-management
[14] Red Hat Software, « Ansible IT automation », https://github.com/ansible/ansible
[15] Guillaume Fournier, code source de « ssh-probe », https://github.com/Gui774ume/ssh-probe
[16] OpenSSH, https://www.openssh.com
[17] Jonathan Corbet, « BPF: the universal in-kernel virtual machine », https://lwn.net/Articles/599755
[18] Lorenzo Fontana, David Calavera, « Linux Observability with BPF », O'Reilly Media, novembre 2019
[19] Linux, « Kprobe documentation », https://www.kernel.org/doc/Documentation/kprobes.txt
[20] Linux, « Tracepoint documentation », https://www.kernel.org/doc/html/latest/trace/tracepoints.html
[21] Jonathan Corbet, « BPF-based error injection for the kernel », https://lwn.net/Articles/740146
[22] Linux, « eBPF helpers documentation », https://man7.org/linux/man-pages/man7/bpf-helpers.7.html
[23] KP Singh, « Kernel Runtime Security Instrumentation », https://lwn.net/Articles/798918