У меня есть сервер AWS под управлением Ubuntu, на котором есть сервер pptpd для VPN и множество клиентов с разными учетными данными. Отлично работает. Но, видимо, я не должен больше использовать это, я должен использовать ipsec. Я сначала пробую это на локальном компьютере под управлением Ubuntu 16.04, прежде чем пытаться сделать это на живом сервере.
Единственный подходящий учебник, который я смог найти, был этот. Другие, похоже, предназначены для VPN типа "сеть-сеть", когда у меня есть настройка "воина на дороге", или для других операционных систем, или просто кажутся нацеленными на системных администраторов, которые делают это каждый день (никто не платит мне за это ).
https://raymii.org/s/tutorials/IPSEC_vpn_with_Ubuntu_16.04.html
В учебнике сказано использовать сертификаты для аутентификации, потому что их «проще использовать».
Я следовал инструкциям. Сервер называется "зимний" и находится по адресу 192.168.3.144. Клиент называется «charly» и находится по адресу 192.168.3.138. Я сгенерировал сертификат сервера следующим образом:
ipsec pki --pub --in private/vpnHostKey.der --type rsa | ipsec pki --issue --lifetime 730 --cacert cacerts/strongswanCert.der --cakey private/strongswanKey.der --dn "C=CN, O=Winter, CN=winter.lan" --san winter --san 192.168.3.144 --san @192.168.3.144 --flag serverAuth --flag ikeIntermediate --outform der > certs/vpnHostCert.der
Системный журнал показывает:
May 30 20:34:36 winter charon: 03[CFG] adding virtual IP address pool 2002:25f7:7489:3::/112
May 30 20:34:36 winter charon: 03[CFG] loaded certificate "C=CN, O=Winter, CN=winter.lan" from 'vpnHostCert.der'
May 30 20:34:36 winter charon: 03[CFG] id 'winter.lan' not confirmed by certificate, defaulting to 'C=CN, O=Winter, CN=winter.lan'
Раздел подключений в sudo ipsec statusall выглядит так:
Connections:
IPSec-IKEv2: %any...%any IKEv2, dpddelay=300s
IPSec-IKEv2: local: [C=CN, O=Winter, CN=winter.lan] uses public key authentication
IPSec-IKEv2: cert: "C=CN, O=Winter, CN=winter.lan"
IPSec-IKEv2: remote: uses public key authentication
IPSec-IKEv2: child: 0.0.0.0/0 === dynamic TUNNEL, dpdaction=clear
Я создал такой сертификат клиента:
cat Charly-public.der | sudo ipsec pki --issue --lifetime 730 --cacert /etc/ipsec.d/cacerts/strongswanCert.der --cakey /etc/ipsec.d/private/strongswanKey.der --dn "C=CN, O=Winter, CN=mat@winter.lan" --san "mat@winter" --san "mat@192.168.3.144" --outform der > Charly-cert.der
... и теперь я пытаюсь подключиться, используя свой Macbook под управлением macOS 10.13.4. Я настраиваю Macintosh VPN как:
... и передайте ему сертификат, который я создал в настройках аутентификации.
Когда я пытаюсь подключиться, он сразу же выходит из строя, без сообщения об ошибке. В журнале сервера:
May 30 20:53:15 winter charon: 06[CFG] looking for peer configs matching 192.168.3.144[mat@winter.lan]...192.168.3.138[192.168.3.138]
May 30 20:53:15 winter charon: 06[CFG] peer config match local: 0 (ID_RFC822_ADDR -> 6d:61:74:40:77:69:6e:74:65:72:2e:6c:61:6e)
May 30 20:53:15 winter charon: 06[CFG] peer config match remote: 1 (ID_IPV4_ADDR -> c0:a8:03:8a)
May 30 20:53:15 winter charon: 06[CFG] ike config match: 28 (192.168.3.144 192.168.3.138 IKEv2)
May 30 20:53:15 winter charon: 06[CFG] no matching peer config found
Вот левая и правая конфигурация:
mat@winter:~$ sudo grep -E 'left|right' /etc/ipsec.conf
left=%any
leftid=winter.lan
leftsubnet=0.0.0.0/0
leftcert=vpnHostCert.der
leftsendcert=always
right=%any
rightsourceip=10.42.42.0/24,2002:25f7:7489:3::/112
rightdns=8.8.8.8,2001:4860:4860::8888
Мой реальный вопрос: что означает «поиск конфигураций одноранговых узлов, соответствующих 192.168.3.144 [mat @ winter] ... 192.168.3.138 [192.168.3.138] / не найдена соответствующая конфигурация однорангового узла»? Я не понимаю, как работает сопоставление - какие значения будут приемлемыми, какие значения отправляются клиентом и как я контролирую их на стороне клиента и сервера. И я не понимаю, как разбирать эту строку, что представляет собой каждый из разделов.
Спасибо!
На этот вопрос был дан правильный ответ ниже, но вот мое объяснение того, что я сделал не так, в терминах, которые я понимаю. tl; dr: leftid должен быть в сертификате как SAN, а не только как CN в DN.
Идея состоит в том, чтобы соединить два сертификата, сертификат сервера и сертификат клиента, чтобы обе стороны могли доверять друг другу. Оба сертификата были подписаны центром сертификации («CA»), и обе стороны имеют открытый ключ CA. Если обе стороны признают, что сертификаты друг друга были подписаны одним и тем же ЦС, они будут счастливы. Проблема заключается в том, чтобы убедить StrongSwan распознать, что входящее клиентское соединение хочет подключиться к определенному сертификату сервера. Мне это кажется легкой задачей, поскольку я настроил только один сертификат. Но StrongSwan предназначен для более сложных настроек.
Важнейшим компонентом является "leftid", настроенный в ipsec.conf. В StrongSwan вы можете настроить любое количество отдельных VPN, каждая из которых будет отличаться своим левым полем. Когда клиент подключается, он запрашивает VPN с этим именем, которое в моем случае настраивается в настройках VPN в разделе «Remote ID». Затем он ожидает, что сервер отправит ему сертификат, и этот сертификат должен идентифицировать себя как то же самое имя VPN / leftid / Remote ID.
Итак, StrongSwan нужен сертификат для лефтида. Вы генерируете сертификат сервера с помощью ipsec. Вы указываете «Отличительное имя» («DN»), которое представляет собой длинную строку компонентов, например «C = CN, O = Winter, CN = winter.lan». Вы также можете указать любое количество альтернативных имен субъектов («SAN»). Когда сервер запускается, он считывает конфигурацию "leftid" и "leftcert". Он пытается найти левый номер в DN или SAN.
Вот трюк: если он не может найти левый конец, он отбрасывает левый и вместо этого просто использует весь DN. Это выглядит так:
May 30 20:34:36 winter charon: 03[CFG] id 'winter.lan' not confirmed by certificate, defaulting to 'C=CN, O=Winter, CN=winter.lan'
Это означает, что VPN теперь больше не называется «winter.lan», а называется «C = CN, O = Winter, CN = winter.lan». Если клиент хочет подключиться, он должен запросить это имя, а не «winter.lan». Это вроде как имеет смысл, потому что, если имя не совпадает, нет смысла даже работать. Клиенты могут подключаться к winter.lan, но если сервер отправит этот сертификат, он не будет соответствовать тому, что запрашивал клиент, и клиент прервет соединение. С другой стороны, это настоящий облом, потому что нет способа убедить Macintosh попросить этот левый.
Большая проблема в руководстве, которому я следил, заключается в том, что левый идентификатор, который он использует, - это "vpn.example.org", а в предложенной команде ipsec для генерации сертификата сервера, который используется только в DN, а не добавляется как SAN. Если я сделаю это с помощью «winter.lan», ничего не получится. Идентификатор не соответствует сертификату.
May 31 21:32:00 winter charon: 05[CFG] loaded certificate "C=CN, O=Winter, CN=winter.lan" from 'vpnHostCert.der'
May 31 21:32:00 winter charon: 05[CFG] id 'winter.lan' not confirmed by certificate, defaulting to 'C=CN, O=Winter, CN=winter.lan'
Это работает, только если я также предоставлю leftid как SAN с --san. В руководстве даже говорится: «вам нужно убедиться, что leftid = совпадает с номером CN в вашем сертификате». Я не знаю, используют ли они другую версию strongswan, чем я, или в чем проблема.
Дополнительная путаница возникает из-за того, что неясно, когда и где строка «C = CN, O = Winter, CN = winter.lan» соответствует строке «winter.lan». Это может быть связано с тем, что к этим идентификаторам также прикреплены «типы», которые должны совпадать, и эти типы обычно не видны в журналах.
В любом случае, самое важное - это строка «не подтверждено сертификатом» при запуске сервера. Не пытайтесь подключиться к клиенту, пока это не будет исправлено.
Одно из расширений subjectAltName, которые вы добавили в сертификат: mat@winter.lan
однако вы настроили leftid=mat@winter
. Поскольку это не совпадает, локальная идентификация вернется к DN субъекта сертификата (т.е. C=HK, O=Winter, CN=mat@winter
). Это, в свою очередь, не соответствует удаленной идентификации, предложенной клиентом (looking for peer configs matching 192.168.3.144[mat@winter]
).
Так что либо настройте leftid=mat@winter.lan
и соответствующим образом измените удаленный идентификатор в конфигурации клиента или настройте полное DN субъекта как удаленное удостоверение на клиенте (но некоторые клиенты IKEv2 на самом деле не поддерживают это, в первую очередь клиенты Apple).
С вашей обновленной конфигурацией, winter.lan
должен содержаться как subjectAltName. Он не будет сравниваться с CN
относительный DN субъекта DN. Итак, вам нужно явно добавить --san winter.lan
при выдаче сертификата сервера.
Если настроенное локальное удостоверение не соответствует ни одному из удостоверений в локальном сертификате (DN субъекта или любое из subjectAltNames - обратите внимание, что тип также должен совпадать), DN субъекта будет использоваться как удостоверение. При загрузке конфига в журнале появляется соответствующее сообщение (что-то вроде id 'mat@winter' not confirmed by certificate, defaulting to 'C=HK, O=Winter, CN=mat@winter'
), и это также можно увидеть в выводе ipsec statusall
в Connections
раздел, в котором перечислены настроенные IP-адреса и идентификаторы. Поэтому убедитесь, что настроенное вами удостоверение - это то, что демон IKE фактически будет использовать во время аутентификации.
Компоненты looking for peer config...
сообщения журнала действительно довольно просты. Например 192.168.3.144[mat@winter]...192.168.3.138[192.168.3.138]
:
Обратите внимание, что тип сравниваемых идентификаторов (например, FQDN или USER_FQDN или KEY_ID) также должен совпадать (идентификаторы могут выглядеть одинаково в журнале и, например, ipsec statusall
но их тип мог быть другим). Более подробная информация об этом сравнении (включая тип) регистрируется, только если уровень журнала для cfg увеличивается до 3.
Идентичность имеет значение по двум причинам. Во-первых, они позволяют выбрать конкретную конфигурацию. Таким образом, отправляя конкретный идентификатор в полезной нагрузке IDr, клиент заявляет, что он хочет подключиться к серверу с этим конкретным идентификатором, и сервер выберет конфигурацию, соответствующую этому идентификатору. Полезная нагрузка является необязательной, и некоторые клиенты ее не отправляют (например, клиенты Windows), что позволяет серверу выбирать любую конфигурацию, которую он считает подходящей. То же самое касается идентификаторов клиентов, которые позволяют серверу переключаться на определенную конфигурацию, если она не соответствует (однако, с правый =% любой, по умолчанию, идентификация клиента будет проигнорирована при выборе конфигураций - но это должно быть подтверждено по сертификату клиента).
Во-вторых, идентификационные данные важны для предотвращения того, чтобы кто-либо, имеющий действующий сертификат, аутентифицировал себя, используя любую личность, которая ему нравится. Например, если на вашем клиенте установлены другие центры сертификации, помимо вашего центра сертификации «X», и вы не применяете конкретную идентификацию (обычно они соответствуют имени хоста сервера), клиент примет любой сертификат, выданный любым из них. ЦС, а не только один, выпущенный специально для этого идентификатора / имени хоста (он даже будет принимать другой сертификат клиента в качестве сертификата сервера, если ЦС «X» является единственным доверенным ЦС, если он не будет обеспечивать соблюдение конкретной идентификации сервера). То же самое и с клиентами. Вы не хотите, чтобы ваш клиент «Y» аутентифицировал себя как клиент «Z» с сертификатом, который был специально выдан клиенту «Y». Это особенно важно, если существует несколько определений подключения с разными праведный настройки и например различные подсети или виртуальные диапазоны IP-адресов, чтобы разрешить доступ к разным сетям через VPN в зависимости от личности клиента.
Большая проблема в руководстве, которому я следил, заключается в том, что левый идентификатор, который он использует, - это "vpn.example.org", а в предложенной команде ipsec для генерации сертификата сервера, который используется только в DN, а не добавляется как SAN.
Да, по какой-то причине они добавляют две несвязанные сети SAN с разными TLD (.com
и .net
) к сертификату.
В руководстве даже говорится: «вам нужно убедиться, что leftid = совпадает с номером CN в вашем сертификате». Я не знаю, используют ли они другую версию strongswan, чем я, или в чем проблема.
Это зависит не от версии strongSwan, а от клиента. Если он не отправляет удаленное удостоверение, сервер может выбрать конфигурацию, которая использует полное DN субъекта в качестве удостоверения. Затем клиент принимает решение о том, принимает ли он это удостоверение, когда оно возвращается сервером. Таким образом, клиенты, которые соответствуют удаленному идентификатору, который они хотят принудительно применить (например, FQDN сервера) к CN DN, отправленного сервером, будут в порядке. Клиенты Windows делают это, клиенты Apple, возможно, тоже (хотя для некоторых версий macOS также требуется соответствующий SAN). Но strongSwan как клиент не требует и будет требовать, чтобы настроенный удаленный идентификатор полностью соответствовал идентификатору, возвращаемому сервером (и его типу). Есть особая конфигурация клиента (rightid =% vpn.example.com), в котором strongSwan не отправляет удаленное удостоверение, а также сопоставляет настроенное удостоверение со всеми удостоверениями в сертификате сервера. Это позволяет клиенту применять полное доменное имя в качестве идентификатора, в то время как сервер идентифицирует себя с полным DN субъекта, если это полное доменное имя также содержится в сертификате сервера как subjectAltName.
Дополнительный уровень путаницы возникает из-за того, что неясно, когда и где строка «C = CN, O = Winter, CN = winter.lan» соответствует строке «winter.lan». Это может быть связано с тем, что к этим идентификаторам также прикреплены «типы», которые должны совпадать, и эти типы обычно не видны в журналах.
Это главным образом потому, что strongSwan не сопоставляет идентификаторы с частями DN. Но, как упоминалось выше, некоторые клиенты делают это (по крайней мере, они сопоставляют FQDN с CN).
В любом случае, самое важное - это строка «не подтверждено сертификатом» при запуске сервера. Не пытайтесь подключиться к клиенту, пока это не будет исправлено.
Это определенно хорошая идея проверить это сообщение журнала или вывод ipsec statusall
соответствует предполагаемой конфигурации.
И если клиенты не могут подключиться к no matching peer config found
, не забудьте сравнить IP-адреса и идентификаторы, указанные в looking for peer configs...
сообщение журнала по IP-адресам и идентификаторам настроенных подключений в ipsec statusall
.