Як створити самопідписаний сертифікат для доменного імені для розробки?


123

У мене є subdomain.example.comте, що я використовую в цілях розвитку. Моє рішення для веб-додатків містить веб-API тощо, що мені потрібно дзвонити із зовнішніх систем, отже, я не використовую localhost.

Зараз мені потрібно перевірити наявність SSL і мені потрібен сертифікат на моє subdomain.example.comдоменне ім'я розробки.

Я спробував створити самопідписаний сертифікат, як зазначено в http://technet.microsoft.com/en-us/library/cc753127(v=ws.10).aspx , але цей сертифікат працює лише для localhost. Чи можна цей сертифікат використовувати для моїх цілей або мені доведеться створити власний підпис для свого субдомену розробки? Якщо мені потрібно створити самопідписану сертифікацію для свого піддомену розробки, яку утиліту чи онлайн-сервіс (безкоштовний) я можу використовувати для цього?

Відповіді:


133

Завдяки функції самопідписання сертифіката IIS ви не можете встановити загальне ім'я (CN) для сертифіката, і тому не можете створити сертифікат, прив'язаний до вашого вибору субдомену.

Одним із способів вирішити проблему є використання makecert.exe, який постачається в комплекті з .Net 2.0 SDK. На моєму сервері це за адресою:

C:\Program Files\Microsoft.Net\SDK\v2.0 64bit\Bin\makecert.exe

Ви можете створити авторизацію підпису та зберігати її у сховищі сертифікатів LocalMachine наступним чином (ці команди повинні бути запущені з облікового запису адміністратора або в підвищеному командному рядку):

makecert.exe -n "CN=My Company Development Root CA,O=My Company,
 OU=Development,L=Wallkill,S=NY,C=US" -pe -ss Root -sr LocalMachine
 -sky exchange -m 120 -a sha1 -len 2048 -r

Потім ви можете створити сертифікат, прив'язаний до вашого субдомену та підписаний вашим новим органом:

(Зверніть увагу, що значення параметра -in має бути таким же, як значення CN, яке використовується для генерування ваших повноважень вище.)

makecert.exe -n "CN=subdomain.example.com" -pe -ss My -sr LocalMachine
 -sky exchange -m 120 -in "My Company Development Root CA" -is Root
 -ir LocalMachine -a sha1 -eku 1.3.6.1.5.5.7.3.1

Потім ваш сертифікат повинен з’явитися в IIS Manager, щоб він був прив’язаний до вашого сайту, як пояснено у публікації Тома Холла.

Всі кудо за це рішення Майку О'Браєну за його чудову публікацію в блозі за адресою http://www.mikeobrien.net/blog/creating-self-signed-wildcard


8
Мені вдалося зробити цю роботу. Мені довелося використовувати командний рядок Visual Studio 2010, makecert.exeщоб бути на моєму шляху. Щодо сертифікатів, я вважав, що я буду більш захищеним та використаним -a SHA512 -len 8192- це генерується назавжди. І, як я підозрював, це може мати нульовий вплив на рівень використовуваного IIS шифрування. За замовчуванням IIS використовує 128-бітове, ви повинні зробити групову політику річ , щоб змінити це. Додатково зверніть увагу на інших читачів: після цього не змінюйте магічні числа -eku, вони потрібні.
BrainSlugs83

3
Запустіть усі вищезазначені команди з командного рядка з адміністративними привілеями, інакше ви отримаєте повідомлення "Помилка: збереження закодованого сертифіката для зберігання не вдалося => 0x5".
Giles Roberts

1
Я також хотів би поділитися чудовим посиланням Створення сертифікатів самопідписаних з makecert.exe для розробки . Посилання пояснює покроковий підхід до створення кореневого сертифіката, сертифіката сервера та сертифікату клієнта. Плюс є пост для пояснення способів їх використання.
Вікрам Сінгх Саїні

3
Веб-переглядачі, як Chrome, почали застарівати sha1. Замініть -a sha512і подумайте про додавання -len 2048до другого makecertвиклику, і все повинно бути добре.
О. Джонс

2
Зауважте, що це більше не працює (принаймні, як показано вище) у Windows 10. Мені довелося замість цього використовувати командлет PowerShell, який працював без проблем.
DVK

120

Використання PowerShell

З Windows 8.1 та Windows Server 2012 R2 (Windows PowerShell 4.0) і вище, ви можете створити сертифікат, який підписав самостійно, використовуючи новий New-SelfSignedCertificateкомандлет:

Приклади:

New-SelfSignedCertificate -DnsName www.mydomain.com -CertStoreLocation cert:\LocalMachine\My

New-SelfSignedCertificate -DnsName subdomain.mydomain.com -CertStoreLocation cert:\LocalMachine\My

New-SelfSignedCertificate -DnsName *.mydomain.com -CertStoreLocation cert:\LocalMachine\My

Використання IIS Manager

  1. Запустіть менеджера IIS
  2. На рівні сервера під IIS виберіть Сертифікати сервера
  3. Праворуч у розділі Дії виберіть Створити самопідписаний сертифікат
  4. Там, де написано "Вкажіть дружнє ім'я для сертифіката" у відповідному імені для довідки.
    1. Приклади: www.domain.comабоsubdomain.domain.com
  5. Потім виберіть свій веб-сайт зі списку зліва
  6. Праворуч у розділі Дії виберіть Прив'язки
  7. Додайте нову прив'язку HTTPS та виберіть створений вами сертифікат (якщо ваш сертифікат є сертифікатом підстановки, вам потрібно вказати ім'я хоста)
  8. Клацніть ОК і протестуйте його

7
+1 для рішення PowerShell. Швидко та просто, і після цього новий сертифікат з'явився в моєму менеджері IIS> Підключення> Сайти> [Мій додаток]> Редагувати прив’язки> Редагувати> Спадне меню сертифіката SSL.
Джон Шнайдер

3
Дотримуючись вищевказаних інструкцій, а потім переглянувши сертифікат, інструкції не заповнюють поле CN, яке все ще має ім'я localhost.
daveD

7
Саме так. Це неправильно! "Дружнє ім'я" не має нічого спільного з CN. Я не знаю, чому ця відповідь має стільки відгуків?
c00000fd

25
Це викликає актуальність, оскільки метод Пауершелла справді працює. (Див. Відповідь @DivineOps) Ось команда, яку я використав: New-SelfSignedCertificate -FriendlyName *.mydomain.local -DnsName *.mydomain.local, localhost -CertStoreLocation Cert:\LocalMachine\MyЦе створює сертифікат в особистому магазині. Потім я спочатку експортував файл cert у файл, а потім повторно імпортував його до обох IIS через IIS Manager (щоб використовувати його для мого https прив'язки), а потім до Trusted Root CA через MMC (щоб уникнути попереджень браузера).
Антон

3
-NotAfterОпція також зручно вказати дату закінчення терміну дії (без нього, за замовчуванням тільки 1 рік). Приклад, який я використавNew-SelfSignedCertificate -DnsName *.mydomain.com -FriendlyName *.mydomain.com -NotAfter (Get-Date).AddYears(15) -CertStoreLocation cert:\LocalMachine\My
Бен Амада

52

Щоб створити новий сертифікат для вашого конкретного домену:

Відкрийте Powershell ISE як адміністратор, запустіть команду:

New-SelfSignedCertificate -DnsName *.mydomain.com, localhost -CertStoreLocation cert:\LocalMachine\My

Щоб довірити новому сертифікату:

  • Відкрити mmc.exe
  • Перейдіть до кореня консолі -> сертифікати (локальний комп'ютер) -> персональний
  • Виберіть створений вами сертифікат, клацніть правою кнопкою миші -> Усі завдання -> Експортуйте та дотримуйтесь майстра експорту, щоб створити .pfx файл
  • Перейдіть до кореня консолі -> сертифікати -> довірені органи сертифікації кореня та імпортуйте новий .pfx файл

Щоб прив’язати сертифікат до свого сайту:

  • Відкрийте менеджер IIS
  • Виберіть свій сайт та виберіть Правка сайту -> Прив’язки на правій панелі
  • Додайте нове прив'язку https з правильним іменем хоста та новим сертифікатом

2
Це працює лише в Windows 8.1 та Windows Server 2012 R2 (Windows PowerShell 4.0) або пізнішої версії, хоча ви можете генерувати сертифікат в одній із цих ОС та імпортувати його пізніше на інший комп'ютер (я щойно зробив це для використання цього сертифіката з SSRS встановлений у Windows Server 2008 R2).
mprost

2
Замість того, щоб експортувати та імпортувати, щоб скопіювати його до довірених кореневих сертифікаційних органів, ви можете просто скопіювати та вставити
jk7

Копіювати / вставляти працює лише на одному сервері. Ви також можете ctrl перетягнути сертифікат з папки "Особисті" до довірених кореневих органів сертифікації на тому ж сервері. Якщо ви хочете, щоб інший хост мав змогу отримати доступ до сайту без попереджень, вам потрібно буде експортувати його та змусити імпортувати сертифікат у свій локальний TRCA (не потрібно включати приватний ключ).
jessewolfe

41

Мені довелося розбирати головоломку через самопідписані сертифікати для Windows, комбінуючи біти та фрагменти з поданих відповідей та подальших ресурсів. Ось моя власна (і, сподіваюся, повна) покрокова програма. Сподіваюся, це позбавить вас від моєї власної болісної кривої навчання. Він також містить інформацію про пов'язані теми, які рано чи пізно з’являться під час створення власних сертифікатів.

Створіть самопідписаний сертифікат у Windows 10 та нижче

Не використовуйте makecert.exe. Корпорація Microsoft застаріла.
Сучасний спосіб використовує команду Powershell.

Windows 10:

Відкрийте Powershell з правами адміністратора:

New-SelfSignedCertificate  -DnsName "*.dev.local", "dev.local", "localhost"  -CertStoreLocation cert:\LocalMachine\My  -FriendlyName "Dev Cert *.dev.local, dev.local, localhost"  -NotAfter (Get-Date).AddYears(15)

Windows 8, Windows Server 2012 R2:

У Powershell для цих систем параметри -FriendlyName та -NotAfter не існують. Просто видаліть їх із вищевказаного командного рядка.
Відкрийте Powershell з правами адміністратора:

New-SelfSignedCertificate  -DnsName "*.dev.local", "dev.local", "localhost"  -CertStoreLocation cert:\LocalMachine\My

Альтернативою є використання методу для старшої версії Windows нижче, що дозволяє використовувати всі функції Win 10 для створення cert ...

Старіші версії Windows:

Моя рекомендація для старих версій Windows - створити cert на машині Win 10, експортувати його у файл .PFX за допомогою екземпляра mmc (див. "Довіряти сертифікату" нижче) та імпортувати його в сховище cert на цільовій машині за допомогою стара ОС Windows. Щоб імпортувати cert, НЕ клацніть його правою кнопкою миші. Хоча в контекстному меню є пункт "Імпорт сертифіката", він не зміг усі мої випробування використовувати його на Win Server 2008. Замість цього відкрийте інший екземпляр mmc на цільовій машині, перейдіть до пункту "Сертифікати (локальний комп'ютер) / Особисті / Сертифікати" , клацніть правою кнопкою миші на середній панелі та виберіть Усі завдання → Імпорт.

Отриманий сертифікат

Обидві вищевказані команди створюють сертифікат для доменів localhost і *.dev.local.
Крім того, у версії Win10 додатково передбачено тривалість роботи 15 років та читабельну назву "Dev Cert * .dev.local, dev.local, localhost".

Оновлення: Якщо ви введете кілька параметрів імені хоста в параметрі -DnsName(як показано вище), перша з цих записів стане Темою домену (Загальна назва AKA). Повний список усіх записів імені хоста буде зберігатися у полі Альтернативна назва предмета (SAN) сертифіката. (Дякуємо @BenSewards, що вказали на це.)

Після створення сертифікат буде негайно доступний у будь-яких HTTPS-прив'язках IIS (інструкції нижче).

Довіряйте сертифікату

Новий сертифікат не є частиною жодної ланцюга довіри, і тому браузери не вважаються надійними. Щоб змінити це, ми скопіюємо сертифікат у сховище сертифікатів для довірених кореневих серверів на вашій машині:

Відкрийте mmc.exe, файл → Додати / видалити оснащення → виберіть "Сертифікати" у лівій колонці → Додати → виберіть "Обліковий запис комп'ютера" → Далі → "Місцевий комп'ютер ..." → Завершити → ОК

У лівій колонці виберіть "Сертифікати (локальний комп'ютер) / Особисті / Сертифікати".
Знайдіть новостворений сертифікат (у програмі Win 10 стовпець "Дружнє ім'я" може допомогти).
Виберіть цей сертифікат і натисніть Ctrl-C, щоб скопіювати його у буфер обміну.

У лівій колонці виберіть "Сертифікати (локальний комп'ютер) / довірені кореневі адміністративні центри / сертифікати".
Натисніть Ctrl-V, щоб вставити свій сертифікат у цей магазин.
Сертифікат повинен міститись у списку довірених кореневих властей і тепер вважається надійним.

Використання в IIS

Тепер ви можете зайти до менеджера IIS, вибрати прив'язки локального веб-сайту → Додати → https → ввести ім'я хосту форми myname.dev.local(ваш сервер дійсний лише для *.dev.local) та вибрати новий сертифікат → ОК.

Додати в хости

Також додайте ім'я хоста до C: \ Windows \ System32 \ driver \ etc \ hosts:

127.0.0.1  myname.dev.local

Щасливі

Тепер Chrome і IE повинні розглядати цей сертифікат як надійний і завантажувати ваш веб-сайт, коли ви відкриваєтесь https://myname.dev.local.

Firefox підтримує власний магазин сертифікатів. Щоб додати сюди сертифікат, потрібно відкрити свій веб-сайт у FF та додати його до винятків, коли FF попереджає вас про сертифікат.

Для браузера Edge може знадобитися більше дій (див. Далі внизу).

Перевірте сертифікат

Щоб перевірити ваші серти, Firefox - ваш найкращий вибір. (Повірте, я сам фанат Chrome, але FF в цьому випадку кращий.)

Ось причини:

  • Firefox використовує власний кеш SSL, який очищається під час перезавантаження. Таким чином, будь-які зміни в сертах ваших локальних веб-сайтів негайно відобразяться в попередженнях FF, тоді як іншим браузерам може знадобитися перезапуск або ручна очистка кешу Windows SSL.
  • Також FF дає кілька цінних підказок, щоб перевірити дійсність вашого сертифіката: Клацніть на Розширено, коли FF показує своє попередження про сертифікат. FF покаже вам короткий текстовий блок з одним або декількома можливими попередженнями в центральних рядках текстового блоку:

Сертифікату не довіряють, оскільки він підписаний самостійно.

Це попередження правильне! Як зазначалося вище, Firefox не використовує сховище сертифікатів Windows і довірятиме цьому сертифікату лише у тому випадку, якщо ви додасте до нього виняток. Кнопка для цього знаходиться прямо під попередженнями.

Сертифікат не дійсний для імені ...

Це попередження показує, що ви щось зробили не так. Домен (wildcard) вашого сертифіката не відповідає домену вашого веб-сайту. Проблему потрібно вирішити, змінивши (під) домен вашого веб-сайту або видавши новий сертифікат, який відповідає. Насправді ви можете додати виняток у FF, навіть якщо сертифікат не відповідає, але ви ніколи не отримаєте зелений символ замка в Chrome з такою комбінацією.

Firefox може відображати в цьому місці безліч інших приємних і зрозумілих попереджень cert, таких як термін з минулим терміном, certs із застарілими алгоритмами підписання і т.д.

Який (під-) доменний шаблон слід вибрати?

У наведеній вище команді New-SelfSignedCertificate ми використовували домен wildcard *.dev.local.

Ви можете подумати: Чому б не використовувати *.local?

Проста причина. Це незаконне домен підстановки.
Сертифікати підстановки повинні містити принаймні доменне ім’я другого рівня.

Отже, домени форми *.localприємно розробляти веб-сайти HTTP. Але не стільки для HTTPS, тому що ви змушені були б видати новий сертифікат відповідності для кожного нового проекту, який ви починаєте.

Важливі бічні примітки:

  • Дійсні хостові домени ТОЛЬКІ можуть містити букви через z, цифри, дефіси та крапки. Підкреслення не дозволено! Деякі веб-переглядачі дуже прискіпливі до цієї деталі і можуть завадити, коли вони вперто відмовляються відповідати ваш домен motör_head.dev.localвашим шаблоном *.dev.local. Вони будуть відповідати, коли ви переходите на motoer-head.dev.local.
  • Підстановочна карта в сертифікаті буде відповідати лише одному ярлику (= розділ між двома точками) у домені, ніколи більше. *.dev.local сірники, myname.dev.local але НЕ other.myname.dev.local!
  • Багаторівневі подвійні символи ( *.*.dev.local) НЕ можливі в сертифікатах. Тож other.myname.dev.localможе бути прикрита лише символом форми *.myname.dev.local. Як результат, найкраще не використовувати доменну частину четвертого рівня. Розмістіть усі свої варіації у частині третього рівня. Таким чином, ви отримаєте разом з одним сертифікатом для всіх ваших сайтів розробників.

Проблема з Edge

Мова йде не про самопідписані сертифікати, але все-таки пов'язані з усім процесом:
Після виконання вищезазначених кроків Edge може не відображати жодного вмісту при відкритті myname.dev.local.
Причиною є характерна особливість управління мережею Windows 10 для сучасних додатків, яка називається «Мережева ізоляція».

Щоб вирішити цю проблему, відкрийте командний рядок з правами адміністратора та введіть один раз таку команду:

CheckNetIsolation LoopbackExempt -a -n=Microsoft.MicrosoftEdge_8wekyb3d8bbwe

Більше інформації про ізоляцію країв та мереж можна знайти тут: https://blogs.msdn.microsoft.com/msgulfcommunity/2015/07/01/how-to-debug-localhost-on-microsoft-edge/


2
Я хотів би зазначити тут, що перше ім’я DNS також зберігається як ім'я предмета, яке ви, можливо, не хочете бути шаблоном.
Бен Сьюардс

@BenSewards: Дякую, що вказав на це, Бен. Я оновив відповідь, щоб включити інформацію про тему / поле SAN. Чи бачите ви якісь проблеми із тим, щоб мати поле хостингу в полі "Тема" замість поля SAN?
Jpsy

@Jpsy - Це працює для мене локально на сервері, на якому створений самопідписаний сертифікат, але не в Firefox або Chrome на моїх (клієнтських) машинах. Я розумію, appname.dev has a security policy called HTTP Strict Transport Security (HSTS), which means that Firefox can only connect to it securely. You can’t add an exception to visit this site.що, як зазначається, не дозволяє додавати клієнтське виключення, всупереч вашій інструкції. Це погана конфігурація в самому IIS щодо налаштувань SSL, вимагає SSL та параметрів клієнтських сертифікатів?
Code Maverick

@CodeMaverick: Чи може будь-який випадок заблокувати рекламу чи антивірусне програмне забезпечення? Іншим варіантом може бути те, що cert не відповідає доменному імені, яке ви використовуєте. Пам'ятайте, що * у сертифікованому CN або SAN може представляти лише один сегмент у доменному імені ( не містить жодних крапок). Таким чином, CN *.mydomain.comможе бути дійсним для, me.mydomain.comале не для me.at.mydomain.com.
Jpsy

14

Я зіткнувся з цією ж проблемою, коли я хотів включити SSL до проекту, розміщеного на IIS 8. Нарешті, інструмент, який я використовував, був OpenSSL , після багатьох днів боротьби з командами makecert. IIS 7 і 8.

Завантажте OpenSSL, сумісний з вашою ОС та цим файлом конфігурації. Встановіть файл конфігурації як конфігурацію за замовчуванням OpenSSL.

Спочатку ми створимо приватний ключ та сертифікат органу з сертифікації (CA). Цей сертифікат призначений для підписання запиту на сертифікат (CSR).

Ви повинні заповнити всі поля, необхідні в цьому процесі.

  1. openssl req -new -x509 -days 3650 -extensions v3_ca -keyout root-cakey.pem -out root-cacert.pem -newkey rsa:4096

Ви можете створити файл конфігурації із налаштуваннями за замовчуванням, як це: Тепер ми згенеруємо запит на сертифікат, який є файлом, який надсилається органам сертифікації.

Загальне ім’я повинно бути встановлено доменом вашого веб-сайту, наприклад: public.organization.com .

  1. openssl req -new -nodes -out server-csr.pem -keyout server-key.pem -newkey rsa:4096

Тепер запит на сертифікат підписується згенерованим сертифікатом CA.

  1. openssl x509 -req -days 365 -CA root-cacert.pem -CAkey root-cakey.pem -CAcreateserial -in server-csr.pem -out server-cert.pem

Згенерований сертифікат повинен бути експортований у файл .pfx, який можна імпортувати в IIS.

  1. openssl pkcs12 -export -out server-cert.pfx -inkey server-key.pem -in server-cert.pem -certfile root-cacert.pem -name "Self Signed Server Certificate"

На цьому кроці ми імпортуємо сертифікат CA.

  1. На вашому сервері необхідно імпортувати сертифікат CA до довірених кореневих сертифікаційних органів, оскільки IIS може довірити імпорт сертифікату. Пам’ятайте, що сертифікат, що імпортується до IIS, був підписаний сертифікатом ЦА.

    • Відкрийте командний рядок і введіть mmc .
    • Натисніть на Файл .
    • Виберіть Додати / Видалити оснащення в ... .
    • Двічі клацніть на Сертифікати .
    • Виберіть Обліковий запис комп'ютера та далі -> .
    • Виберіть Місцевий комп'ютер і Готово .
    • Гаразд .
    • Перейдіть до Сертифікати -> Довірені кореневі органи сертифікації -> Сертифікати , натисніть на Сертифікати та виберіть Усі завдання -> Імпортувати ...

введіть тут опис зображення

  • Виберіть Далі -> Огляд ...
  • Потрібно вибрати Усі файли, щоб переглянути місце файлу root-cacert.pem .
  • Клацніть на Далі та виберіть Розмістити всі сертифікати в наступному магазині : Trusted Root Certification Authority .
  • Клацніть на Далі та Готово .

введіть тут опис зображення

З цим кроком IIS довіряє справжності нашого сертифіката.

  1. На останньому кроці ми імпортуємо сертифікат до IIS та додамо сайт прив’язки.

    • Відкрийте менеджер інформаційних служб Інтернету (IIS) або введіть inetmgr у командному рядку та перейдіть до Сертифікатів сервера .
    • Натисніть на імпорт ... .
    • Встановіть шлях файлу .pfx, парольну фразу та Виберіть зберігання сертифікатів на веб-хостингу .

введіть тут опис зображення

  • Натисніть кнопку ОК .
  • Тепер перейдіть на свій веб-сайт Менеджера IIS і виберіть Прив'язки ... та додайте нову прив'язку.

  • Виберіть https як тип прив'язки, і ви зможете побачити імпортований сертифікат.

  • Натисніть кнопку ОК і все зроблено.

введіть тут опис зображення


Я хотів би мати більш тривалий термін дії з сертифікатом самопідписання, і Windows SDK з makecert.exe був недоступний на хості Windows. Хост Linux та ця відповідь забезпечили рішення.
Річк

Я радий, що ти знайшов корисну мою відповідь.
Йосип

Куди помістити цю "public.organization.com" в команду openssl?
Єдиного

2

Інший варіант - створити сертифікат самопідписання, який дозволяє вказати доменне ім’я на веб-сайті. Це означає, що ви можете використовувати його для багатьох доменних імен.

У IIS Manager

  1. Клацніть вузол імені машини
  2. Відкрийте Сертифікати сервера
  3. На панелі "Дії" виберіть "Створити самопідписаний сертифікат"
  4. У "Вкажіть дружнє ім'я ..." назвіть його * Dev (виберіть "Особисте" зі списку типів)
  5. Зберегти

Тепер на вашому веб-сайті в IIS ...

  1. Керуйте прив’язками
  2. Створіть нову прив'язку для Https
  3. Виберіть зі списку власний підписаний сертифікат
  4. Після вибору вікно доменного імені буде ввімкнено, і ви зможете ввести своє доменне ім’я.

введіть тут опис зображення


Дякую найкориснішій відповіді поки що. Принаймні, використовувати його для розвитку це швидко.
cabaji99

0

Ще один простий спосіб генерувати сертифікат, який підписує сам - це використовувати Jexus Manager,

Менеджер Jexus

  1. Виберіть серверний вузол на панелі «Підключення».
  2. На середній панелі натисніть значок Сертифікати сервера, щоб відкрити сторінку управління.
  3. На панелі "Дії" натисніть пункт меню "Створити самопідписаний сертифікат ...".

https://www.jexusmanager.com/en/latest/tutorials/self-signed.html

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.