Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

proftpd + inetd + ssl/tls и другие вопросы.

117 views
Skip to first unread message

Oleksandr Gavenko

unread,
Nov 23, 2015, 7:40:02 PM11/23/15
to
Выяснил что plain ftp передает пароль в открытом виде в момент авторизации.

Есть https://ru.wikipedia.org/wiki/FTPS в разных версиях / режимах работы.

Не могу вьехать что делать что бы proftpd + inetd работал безопасно.

В общем на сервере выполнил:

$ sudo proftpd-gencert

/etc/proftpd/proftpd.conf::

Include /etc/proftpd/tls.conf

/etc/proftpd/tls.conf::

TLSEngine on
TLSLog /var/log/proftpd/tls.log
TLSProtocol SSLv23

TLSRSACertificateFile /etc/ssl/certs/proftpd.crt
TLSRSACertificateKeyFile /etc/ssl/private/proftpd.key
TLSOptions NoCertRequest EnableDiags
TLSVerifyClient off
TLSRequired on

Пробую:

bash# lftp ftp://user@vps
Password:
lftp user@vps:~> ls
ls: Fatal error: Certificate verification: Not trusted
lftp user@vps:~> exit

bash# lftp -e 'set ssl:verify-certificate no' ftp://user@vps
Password:
lftp user@vps:~> ls
drwxr-xr-x 5 user user 4096 Nov 22 18:04 devel
drwxr-xr-x 2 user user 4096 Oct 10 16:14 tmp

Обычная команда `ftp` из `/usr/bin/netkit-ftp` не поддерживает SSL:

bash# ftp -n vps
Connected to vps.
220 ProFTPD 1.3.5 Server (Debian) [149.202.132.30]
ftp> ls
550 SSL/TLS required on the control channel
ftp: bind: Address already in use
ftp> user user
^C
421 Service not available, remote server has closed connection
ftp> exit

`curl` тоже работает::

$ curl --ftp-ssl -k --netrc ftp://user@vps/.bashrc

Нужно ли в inetd.conf использовать ftps или ftp:

ftp stream tcp nowait root /usr/sbin/tcpd /usr/sbin/proftpd
ftps stream tcp nowait root /usr/sbin/tcpd /usr/sbin/proftpd

У меня на ftps ошибки:

bash# curl --ftp-ssl -k --netrc ftps://user@vps/.bashrc
curl: (35) gnutls_handshake() failed: An unexpected TLS packet was received.

bash# lftp ftps://user@vps
lftp user@vps:~> ls
ls: Fatal error: gnutls_handshake: An unexpected TLS packet was received.

Такое ощущение что для ftps:// используется другой протокол, чем на ftp:// с
включенным SSL.

Как правильно запретить общение открытым текстом и настроить SSL/TLS в proftpd?

Далее вопрос как в Debian сделать публичный ключ proftpd доверенным на
клиентах?

Я пробовал как:

$ sudo mkdir /usr/share/ca-certificates/vps
$ sudo scp user@vps:/etc/ssl/certs/proftpd.crt /usr/share/ca-certificates/vps/proftpd.crt
$ sudo dpkg-reconfigure ca-certificates
$ sudo update-ca-certificates --fresh

Но curl и lftp игнорируют Дебиановские соглашения о сертификатах. Или я
неверно готовлю. При том proftpd.crt виден в конце:

/etc/ssl/certs/ca-certificates.crt

Также если кормить напрямую:

bash# curl -v --ftp-ssl --cacert /usr/share/ca-certificates/vps/proftpd.crt --netrc ftp://user@vps/.bashrc
* Trying 149.202.132.30...
* Connected to vps (149.202.132.30) port 21 (#0)
< 220 ProFTPD 1.3.5 Server (Debian) [149.202.132.30]
> AUTH SSL
< 234 AUTH SSL successful
* found 1 certificates in /usr/share/ca-certificates/vps/proftpd.crt
* found 728 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
* server certificate verification failed. CAfile: /usr/share/ca-certificates/vps/proftpd.crt CRLfile: none
* Closing connection 0
curl: (60) server certificate verification failed. CAfile: /usr/share/ca-certificates/vps/proftpd.crt CRLfile: none
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.

--
Best regards!

Tim Sattarov

unread,
Nov 23, 2015, 11:20:02 PM11/23/15
to
On 23/11/15 07:30 PM, Oleksandr Gavenko wrote:
> Выяснил что plain ftp передает пароль в открытом виде в момент авторизации.
>
> Есть https://ru.wikipedia.org/wiki/FTPS в разных версиях / режимах работы.
>
> Не могу вьехать что делать что бы proftpd + inetd работал безопасно.
>
>
а SFTP или Rsync over SSH не нравится ?

Tim Sattarov

unread,
Nov 23, 2015, 11:30:02 PM11/23/15
to
On 23/11/15 07:30 PM, Oleksandr Gavenko wrote:
>
> bash# lftp ftp://user@vps
> Password:
> lftp user@vps:~> ls
> ls: Fatal error: Certificate verification: Not trusted
> lftp user@vps:~> exit
тут бы я посмотрел на ftp:ssl-* значения
curl попробовать с -k

и смотреть как работает SSL соединение с помощью openssl

openssl s_client -connect vps:990

Tim Sattarov

unread,
Nov 23, 2015, 11:30:02 PM11/23/15
to
On 23/11/15 07:30 PM, Oleksandr Gavenko wrote:
>
> bash# lftp ftp://user@vps
> Password:
> lftp user@vps:~> ls
> ls: Fatal error: Certificate verification: Not trusted
> lftp user@vps:~> exit

Artem Chuprina

unread,
Nov 24, 2015, 1:10:03 AM11/24/15
to
Oleksandr Gavenko -> debian-...@lists.debian.org @ Tue, 24 Nov 2015 02:30:58 +0200:

OG> Выяснил что plain ftp передает пароль в открытом виде в момент авторизации.

OG> Есть https://ru.wikipedia.org/wiki/FTPS в разных версиях / режимах работы.

OG> Не могу вьехать что делать что бы proftpd + inetd работал безопасно.

OG> В общем на сервере выполнил:

OG> $ sudo proftpd-gencert

OG> /etc/proftpd/proftpd.conf::

OG> Include /etc/proftpd/tls.conf

OG> /etc/proftpd/tls.conf::

OG> TLSEngine on
OG> TLSLog /var/log/proftpd/tls.log
OG> TLSProtocol SSLv23

По нынешним временам SSL v2 и v3 считается за "шифрование отсутствует".
В смысле, дыры и их эксплойты в этих версиях протокола известны.

OG> TLSRSACertificateFile /etc/ssl/certs/proftpd.crt
OG> TLSRSACertificateKeyFile /etc/ssl/private/proftpd.key
OG> TLSOptions NoCertRequest EnableDiags
OG> TLSVerifyClient off
OG> TLSRequired on

OG> Пробую:

OG> bash# lftp ftp://user@vps
OG> Password:
OG> lftp user@vps:~> ls
OG> ls: Fatal error: Certificate verification: Not trusted
OG> lftp user@vps:~> exit

OG> bash# lftp -e 'set ssl:verify-certificate no' ftp://user@vps
OG> Password:
OG> lftp user@vps:~> ls
OG> drwxr-xr-x 5 user user 4096 Nov 22 18:04 devel
OG> drwxr-xr-x 2 user user 4096 Oct 10 16:14 tmp

OG> Обычная команда `ftp` из `/usr/bin/netkit-ftp` не поддерживает SSL:

OG> bash# ftp -n vps
OG> Connected to vps.
OG> 220 ProFTPD 1.3.5 Server (Debian) [149.202.132.30]
ftp>> ls
OG> 550 SSL/TLS required on the control channel
OG> ftp: bind: Address already in use
ftp>> user user
OG> ^C
OG> 421 Service not available, remote server has closed connection
ftp>> exit

OG> `curl` тоже работает::

OG> $ curl --ftp-ssl -k --netrc ftp://user@vps/.bashrc

OG> Нужно ли в inetd.conf использовать ftps или ftp:

OG> ftp stream tcp nowait root /usr/sbin/tcpd /usr/sbin/proftpd
OG> ftps stream tcp nowait root /usr/sbin/tcpd /usr/sbin/proftpd

OG> У меня на ftps ошибки:

OG> bash# curl --ftp-ssl -k --netrc ftps://user@vps/.bashrc
OG> curl: (35) gnutls_handshake() failed: An unexpected TLS packet was received.

OG> bash# lftp ftps://user@vps
OG> lftp user@vps:~> ls
OG> ls: Fatal error: gnutls_handshake: An unexpected TLS packet was received.

OG> Такое ощущение что для ftps:// используется другой протокол, чем на ftp:// с
OG> включенным SSL.

Да. ftps начинается с SSL/TLS handshake, и уже только после того, как
защищенное соединение установилось, начинается диалог по протоколу FTP.
В случае с ftp сначала начинается диалог по FTP, внутри него выдается
просьба поднять TLS, и после того, как он поднят, продолжается диалог по
FTP.

OG> Как правильно запретить общение открытым текстом и настроить SSL/TLS в proftpd?

По идее, при настройке TLSRequired on разницы в безопасности быть не
должно - FTP не поддерживает вроде бы pipelining, на USER сервер выдаст
вон то, что он выдает команде ftp, и до пароля дело не дойдет.

OG> Далее вопрос как в Debian сделать публичный ключ proftpd доверенным на
OG> клиентах?

OG> Я пробовал как:

OG> $ sudo mkdir /usr/share/ca-certificates/vps
OG> $ sudo scp user@vps:/etc/ssl/certs/proftpd.crt /usr/share/ca-certificates/vps/proftpd.crt
OG> $ sudo dpkg-reconfigure ca-certificates
OG> $ sudo update-ca-certificates --fresh

OG> Но curl и lftp игнорируют Дебиановские соглашения о сертификатах. Или я
OG> неверно готовлю. При том proftpd.crt виден в конце:

Второе.

Тут, вероятно, для начала нужен некоторый ликбез.

Клиенты доверяют сертификату сервера, если этот сертификат подписан
доверенным центром сертификации. Вот то самое "ca" в ca-certificates.
Certification Authority. У CA тоже есть сертификат, и подпись на
сертификате сервера проверяется об этот сертификат (там содержится
открытый ключ подписи).

Для построения цепочки доверия нужно выполнение нескольких условий.
Применительно к твоей ситуации, не выполнено в первую очередь условие
"сертификат сервера и сертификат CA - разные сертификаты, с разными
разрешенными областями применения".

Чтобы нормально работало, надо сделать честный сертификат CA,
распространить его по клиентам, в норме - установить в набор доверенных
корневых (это то, что ты пытался сделать с сертификатом сервера),
сделать честный серверный сертификат и подписать его ключом CA.

Или купить серверный сертификат у какого-нибудь известного CA, про
которого большинство клиентов знает из коробки. Это минус необходимость
устанавливать свой сертификат CA на клиентов - довольно сложная операция
для юзера на винде (вероятно, разная для разных версий винды),
работоспособная не в каждом андроиде, и т.п.

Я не знаю точно, что именно делает proftpd-gencert, но почти наверняка
он делает самоподписанный сертификат сервера, на котором можно защищать
соединение, но которому в нормальной инфраструктуре никто не будет
доверять.

Сделать честно не то чтобы офигительно сложно, но я не знаю простых
энд-юзерских инструментов для этого. Сам тупо пользуюсь openssl, но я
этой криптографией занимался профессионально, и понимаю, что делать с
его ключами и конфигом. А так-то openssl как утилита - штука
отладочная, для реальной работы не предазначенная. Хотя может.

Вроде бы, в комплекте gnutls было что-то попроще для построения PKI.

OG> /etc/ssl/certs/ca-certificates.crt

OG> Также если кормить напрямую:

OG> bash# curl -v --ftp-ssl --cacert /usr/share/ca-certificates/vps/proftpd.crt --netrc ftp://user@vps/.bashrc
OG> * Trying 149.202.132.30...
OG> * Connected to vps (149.202.132.30) port 21 (#0)
OG> < 220 ProFTPD 1.3.5 Server (Debian) [149.202.132.30]
>> AUTH SSL
OG> < 234 AUTH SSL successful
OG> * found 1 certificates in /usr/share/ca-certificates/vps/proftpd.crt
OG> * found 728 certificates in /etc/ssl/certs
OG> * ALPN, offering http/1.1
OG> * SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
OG> * server certificate verification failed. CAfile: /usr/share/ca-certificates/vps/proftpd.crt CRLfile: none
OG> * Closing connection 0
OG> curl: (60) server certificate verification failed. CAfile: /usr/share/ca-certificates/vps/proftpd.crt CRLfile: none
OG> More details here: http://curl.haxx.se/docs/sslcerts.html

OG> curl performs SSL certificate verification by default, using a "bundle"
OG> of Certificate Authority (CA) public keys (CA certs). If the default
OG> bundle file isn't adequate, you can specify an alternate file
OG> using the --cacert option.
OG> If this HTTPS server uses a certificate signed by a CA represented in
OG> the bundle, the certificate verification probably failed due to a
OG> problem with the certificate (it might be expired, or the name might
OG> not match the domain name in the URL).
OG> If you'd like to turn off curl's verification of the certificate, use
OG> the -k (or --insecure) option.

OG> --
OG> Best regards!

Andrey Melnikoff

unread,
Nov 24, 2015, 3:50:03 AM11/24/15
to
Oleksandr Gavenko <gave...@gmail.com> wrote:

> Выяснил что plain ftp передает пароль в открытом виде в момент авторизации.
Он так лет 30+ последних делает.

> Есть https://ru.wikipedia.org/wiki/FTPS в разных версиях / режимах работы.

> Не могу вьехать что делать что бы proftpd + inetd работал безопасно.
Выкинуть. Это им поможет.
А использовать вместо - sftp. Софтин под винду - валом.

Victor Wagner

unread,
Nov 24, 2015, 4:00:03 AM11/24/15
to
On Tue, 24 Nov 2015 02:30:58 +0200
Oleksandr Gavenko <gave...@gmail.com> wrote:

> Выяснил что plain ftp передает пароль в открытом виде в момент
> авторизации.
>
> Есть https://ru.wikipedia.org/wiki/FTPS в разных версиях / режимах
> работы.
>
> Не могу вьехать что делать что бы proftpd + inetd работал безопасно.

1. Не использовать ftp для неанонимного доступа.
2. Сделать так, чтобы директории, доступные для анонима на запись, не
были доступны для него же на чтение (а то превратят сервер в хаб для
обмена порнухой)
3. Во всех остальных случаях использовать протоколы, отличные от ftp.

Oleksandr Gavenko

unread,
Nov 24, 2015, 4:20:03 AM11/24/15
to
On 2015-11-24, Tim Sattarov wrote:

> а SFTP или Rsync over SSH не нравится ?

Нет опыта работы, сейчас поискал как ограничивать доступ, вот что есть:

Для SFTP решение в виде:

$ sudo groupadd sftp
$ sudo usermod username -g sftp
$ sudo usermod username -s /bin/false
$ sudo usermod username -d /home/username

$ cat /etc/ssh/sshd_config
...
Match Group sftp
ChrootDirectory %h
ForceCommand internal-sftp
AllowTcpForwarding no
...

Или

$ cat /etc/ssh/sshd_config
...
Match User restricted
ChrootDirectory /srv/data/ANY-PATH
ForceCommand internal-sftp
AllowTcpForwarding no
...

Для rsync:

https://www.debian.org/mirror/push_server

$ cat /etc/rsyncd.conf

uid = nobody
gid = nogroup
max connections = 25
socket options = SO_KEEPALIVE

[debian]
path = /srv/debian/mirror
comment = The Debian Archive (~250 GB)
auth users = authorized_account1,authorized_account2,authorized_accountN
read only = true
secrets file = /etc/rsyncd/debian.secrets

$ cat /etc/rsyncd/debian.secrets

authorized_account1:a_password
authorized_account2:another_password
authorized_accountN:password

$ cat /etc/initd

rsync stream tcp nowait root /usr/bin/rsync rsyncd --daemon

Как видно для rsync есть возможность задать синтетические авторизационные
данные, для sftp - только пользователи системы. Этим rsync больше нравится.

--
Best regards!

Oleksandr Gavenko

unread,
Nov 24, 2015, 4:40:04 AM11/24/15
to
On 2015-11-24, Tim Sattarov wrote:

> тут бы я посмотрел на ftp:ssl-* значения
> curl попробовать с -k
>
> и смотреть как работает SSL соединение с помощью openssl
>
> openssl s_client -connect vps:990

Спасибо за подсказку, отладил эту проблему:

bash# openssl s_client -connect vps:990
CONNECTED(00000003)
140416106407568:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:794:
---
no peer certificate available
---
No client certificate CA names sent

bash# lftp -e 'set ssl:verify-certificate no' ftp://user@vps:990
lftp user@vps:~> ls
drwxr-xr-x 5 user user 4096 Nov 22 18:04 devel
drwxr-xr-x 2 user user 4096 Oct 10 16:14 tmp
lftp user@vps:/> exit

Т.е. на ftps у меня не FTP через SSL/TLS, а некое расширение протокола FTP с
SSL/TLS.

Собвтвенно это возвращает меня к вопросу - что же это такое протокол FTPS,
какие клиенты/серверы поддерживают?

--
Best regards!

Oleksandr Gavenko

unread,
Nov 24, 2015, 8:40:04 AM11/24/15
to
On 2015-11-24, Victor Wagner wrote:

> 1. Не использовать ftp для неанонимного доступа.
> 2. Сделать так, чтобы директории, доступные для анонима на запись, не
> были доступны для него же на чтение (а то превратят сервер в хаб для
> обмена порнухой)

Ясно. Я ранее знал практике публичных бесплатных хостингов - позволять
загружать странички через небозопасный FTP. На ум приходит narod.ru и blogspot
до покупки Google'ом.

Ожидал что есть TLS расширение, обеспечивающие безопасность.

Есть стандарт

https://tools.ietf.org/html/rfc2228
FTP Security Extensions

со страшными словами GSSAPI/Kerberos 4, который судя по:

http://www.proftpd.org/docs/rfc.html

не реализован полностью в proftpd. В то же время есть

https://tools.ietf.org/html/rfc4217

который реализован в модуле mod_tls (и согласован с командой AUTH от rfc2228):

http://www.proftpd.org/docs/howto/TLS.html

Оказывается что rfc4217 это не FTP в обертке TLS, а гибрид:

12.1. Establishing a Protected Session

Client Server
control data data control
======================================================

socket()
bind()
socket()
connect() --------------------------------> accept()
<-------------------------------- 220
AUTH TLS -------------------------------->
<-------------------------------- 234
TLSneg() <--------------------------------> TLSneg() <== Тут зашифровано?
PBSZ 0 -------------------------------->
<-------------------------------- 200
PROT P -------------------------------->
<-------------------------------- 200
USER fred -------------------------------->
<-------------------------------- 331
PASS pass -------------------------------->
<-------------------------------- 230

И далее у нас есть возможность передавать данные либо открыто, либо защищенно
по data-каналу.

Стандарта на обертку FTP в TLS, судя по выдержке:

Negotiation is not supported with implicit FTPS configurations. A client is
immediately expected to challenge the FTPS server with a TLS ClientHello
message. If such a message is not received by the FTPS server, the server
should drop the connection.

из:

https://en.wikipedia.org/wiki/FTPS

и:

A. Deprecated SSL negotiation mechanisms

There are two other mechanisms that have been used for FTP over SSL,
these mechanisms do not conform to [RFC-2228] and so are now
deprecated. They are documented below.

i) Implicit SSL protection of the FTP session

There is a port, registered with the IANA, for secure FTP using
ssl {FTP-TLSPORT}. This approach can be likened to the [RFC-2818]
approach for https, in that the SSL negotiation happens upon
connection (for the control and all data connections). This
approach is not favoured by the IETF and should not be used for
new FTP-TLS implementations.
из:

https://tools.ietf.org/html/draft-murray-auth-ftp-ssl-07#appendix-A

нету и нету соответственно нормальных реализаций.

lftp и curl на ftps:// пытаются "пожать руку", proftpd такого скоре всего не
умеет (я в документации не нашел способа).

> 3. Во всех остальных случаях использовать протоколы, отличные от ftp.

Я слышал и некоторые использовал:

* smb - на сколько толстый сервер? У меня vps с 256 MiB RAM и доступ на
запись к файлам не основная задача. Как с безопасностью при авторизации?

* sftp - требует создавать пользователя в системе под каждый разделяемый
ресурс.

* rsync - не знаю визуальных оболочек, например как ftp/sftp в MC и
интерактивных приложений как sftp/lftp. Для безопасности вроде нужно
тунелировать через ssh.

* webdav - требует постоянно работающего apache, нужно настраивать SSL.

Из всего только sftp выглядит простым решением.

Если разобраться с сертификатами, то мне ftps кажется тоже хорошим решением,
особенно учитывая что через ftp-сервер можно задавать права доступа, ложить
файлы с нужными владельцами и правами и использовать свою базу авторизации
(ftpasswd).

--
Best regards!

Victor Wagner

unread,
Nov 24, 2015, 9:00:03 AM11/24/15
to
On Tue, 24 Nov 2015 15:31:59 +0200
Oleksandr Gavenko <gave...@gmail.com> wrote:


> Я слышал и некоторые использовал:
>
> * smb - на сколько толстый сервер? У меня vps с 256 MiB RAM и доступ
> на запись к файлам не основная задача. Как с безопасностью при
> авторизации?


С прошлого века не слышал, чтобы пользовались не в локальной сети.

> * sftp - требует создавать пользователя в системе под каждый
> разделяемый ресурс.


Не вижу никаких преимуществ перед scp или rsync over ssh

И для той, и для другой нужно работать с системными пользователями.
Совершенно не обязательно "пользователя на каждый разделяемый ресурс".
Можно пользователя на каждого пользователя и группу на каждый
разделяемый ресурс.



> * rsync - не знаю визуальных оболочек, например как ftp/sftp в MC и
> интерактивных приложений как sftp/lftp. Для безопасности вроде
> нужно тунелировать через ssh.

Вот у rsync протокол аутентификации достаточно безопасный. Так что если
контент светить не жалко, можно использовать и без ssh.

> * webdav - требует постоянно работающего apache, нужно настраивать
> SSL.

webdav - не знаю удобных клиентов. cadaver неудобный какой-то,
монтирование с помощью davfs не гарантирует своевременной доставки
файлов. С клиентом который бы позволял читать-писать файлы только через
опции командной строки - вообще все плохо. В vim netrw пытается cadaver
использовать, но у него не получается.

А вот в качестве сервера apache cовершенно необязателен. Можно и nginx
какой-нибудь.

А SSL настраиватьп придется и в случае если FTPS использовать. SSL в
любом случае надо настраивать, если хочешь использовать серверную
сторону протокола. Иначе она ничего не защищает.

Еще бы хорошо на клиентской стороне понимать что и зачем, а то опять же
не защищает.




> Если разобраться с сертификатами, то мне ftps кажется тоже хорошим
> решением, особенно учитывая что через ftp-сервер можно задавать права
> доступа, ложить файлы с нужными владельцами и правами и использовать
> свою базу авторизации (ftpasswd).

Если разобраться с сертификатами то DAV в общем-то решает все те же
задачи, только лучше.

Oleksandr Gavenko

unread,
Nov 24, 2015, 7:00:04 PM11/24/15
to
Да, схема то закручена. Вместо прямого доверия cертификату сервера (как я
думал выше что получится) мы доверяем всем сетрификатам подписаными доверенным
CA.

В общем ниже сырой материал, подготовленый для блогозаписи.

Может есть проще (я встречал упоминание о ca.pl скрипте) но так сработало.
openssl.cnf подбирал копированием /usr/lib/ssl/openssl.cnf подряд по
выпадающим ошибкам от "openssl ca". Остальное извлек из кучи вкладок браузера.

Я тоже занимался криптографией (БИФИТ, оптимизация криптопримитивов), но
сменил работу в то время как подоспели прикладные задачи (связать примитивы в
публичные API и PKI), не успел помучится с x509 и PKI ))

================================================================

Create CA root self-signed certificate::

$ openssl req -x509 -sha256 -days 1000 -nodes -newkey rsa:4096 -keyout ca-root-key.pem -out ca-root-cert.pem
...
$ ls ca-root-*.pem
ca-root-cert.pem ca-root-key.pem

Dump content::

$ openssl x509 -text -noout -in ca-root-cert.pem
...
$ openssl pkey -text -noout -in ca-root-key.pem
...

Check certificate purpose::

$ openssl x509 -purpose -in ca-root-cert.pem
...

Generate server key and certificate::

$ openssl req -sha256 -days 1000 -nodes -newkey rsa:4096 -keyout server-key.pem -out server-cert.csr
$ ls server-*.pem
server-cert.csr server-key.pem

Dump content::

$ openssl req -text -noout -in server-cert.csr
...
$ openssl pkey -text -noout -in server-key.pem
...

To fill subject automatically::

$ openssl req -sha256 -days 1000 -nodes -newkey rsa:4096 -subj "/C=UA/ST=User/L=City/O=Corp/OU=SubCorp/CN=myvps.com" -keyout server-key.pem -out server-cert.csr


Prepare use minimal ``openssl.cnf``::

[ ca ]
default_ca = CA_default

[ CA_default ]
new_certs_dir = .
database = index.txt
serial = serial.txt

default_md = default
policy = policy_anything

[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

Prepare some CA database files::

$ echo 01 > serial.txt
$ touch touch index.txt index.txt.attr

Sign server CSR with CA key::

$ openssl ca -days 1000 -config openssl.cnf -cert ca-root-cert.pem -keyfile ca-root-key.pem -out server-cert.pem -in server-cert.csr

Dump signed server certificate::

$ openssl x509 -text -noout -in server-cert.pem
...

Copy CA certificate to Debian tructed store::

$ sudo cp ca-root-cert.pem /usr/share/ca-certificates/my/my-ca-root-cert.crt

and register certificate::

$ sudo dpkg-reconfigure ca-certificate

Copy signed server key + certificate to server and resister it::

$ scp server-key.pem server-cert.pem user@vps
$ ssh user@vps
% sudo cp server-cert.pem /etc/ssl/certs/proftpd.crt
% sudo cp server-key.pem /etc/ssl/private/proftpd.key

After all I can run::

$ lftp ftp://us...@myvps.com
lftp us...@myvps.com:~> ls
-rw-r----- 1 ftp ftp 276 Nov 24 20:16 index.html
lftp us...@myvps.com:/> exit

without::

$ lftp -e 'set ssl:verify-certificate no' ftp://us...@myvps.com

Note that ftp:// URL domain name SHOULD match certificate CN name or you get error::

Fatal error: Certificate verification: certificate common name doesn't match requested host name ‘myvps.com

--
Best regards!

Oleksandr Gavenko

unread,
Nov 24, 2015, 7:20:03 PM11/24/15
to
On 2015-11-24, Victor Wagner wrote:

>> Если разобраться с сертификатами, то мне ftps кажется тоже хорошим
>> решением, особенно учитывая что через ftp-сервер можно задавать права
>> доступа, ложить файлы с нужными владельцами и правами и использовать
>> свою базу авторизации (ftpasswd).
>
> Если разобраться с сертификатами то DAV в общем-то решает все те же
> задачи, только лучше.

У меня когда-то была идея на SVN+WebDAV внедрить репозиторий для артефактов
сборки (вместо FTP, т.к. были случаи когда подменялись библиотеки участвующие
в релизной сборке - нельзя было понять произошло ли это событие и кем/когда).

В SVN хранилище есть контрольные суммы (на сколько я помню также от контента),
позволяет выявить повреждения.

Хранится история кто и когда поместил файл.

Хуками можно запретить перезаписывание файла.

Еще правильней было бы просто подписывать ключем релизера хеши от файлов и в
релизной сборке проверять подписи от довереных pgp клочей, но я такого не
видел в комерческих предприятиях.

Зато встречал стягивание по HTTP (без S) библиотек с Maven-репозиториев.

--
Best regards!

Artem Chuprina

unread,
Nov 25, 2015, 1:50:02 AM11/25/15
to
Oleksandr Gavenko -> debian-...@lists.debian.org @ Wed, 25 Nov 2015 01:50:18 +0200:

Вот меня в нижеприведенном прям смущает, что конфиг совсем
минималистичный. openssl нынче что, сам догадывается поставить
правильное назначение сертификата в зависимости от того, делают его
самоподписанным или подписывают заявку?

Можно посмотреть вывод openssl x509 -text -noout этих обоих сертификатов
в части X509v3 extensions?

У меня для сертификата CA там показывают

X509v3 Basic Constraints:
CA:TRUE
X509v3 Key Usage:
Certificate Sign, CRL Sign

а для сертификата сервера

X509v3 Basic Constraints:
CA:FALSE
Netscape Cert Type:
SSL Server
X509v3 Extended Key Usage:
TLS Web Server Authentication

OG> В общем ниже сырой материал, подготовленый для блогозаписи.

OG> Может есть проще (я встречал упоминание о ca.pl скрипте) но так сработало.
OG> openssl.cnf подбирал копированием /usr/lib/ssl/openssl.cnf подряд по
OG> выпадающим ошибкам от "openssl ca". Остальное извлек из кучи вкладок браузера.

OG> Я тоже занимался криптографией (БИФИТ, оптимизация криптопримитивов), но
OG> сменил работу в то время как подоспели прикладные задачи (связать примитивы в
OG> публичные API и PKI), не успел помучится с x509 и PKI ))

OG> ================================================================

OG> Create CA root self-signed certificate::

OG> $ openssl req -x509 -sha256 -days 1000 -nodes -newkey rsa:4096 -keyout
OG> ca-root-key.pem -out ca-root-cert.pem
OG> ...
OG> $ ls ca-root-*.pem
OG> ca-root-cert.pem ca-root-key.pem

OG> Dump content::

OG> $ openssl x509 -text -noout -in ca-root-cert.pem
OG> ...
OG> $ openssl pkey -text -noout -in ca-root-key.pem
OG> ...

OG> Check certificate purpose::

OG> $ openssl x509 -purpose -in ca-root-cert.pem
OG> ...

OG> Generate server key and certificate::

OG> $ openssl req -sha256 -days 1000 -nodes -newkey rsa:4096 -keyout server-key.pem -out server-cert.csr
OG> $ ls server-*.pem
OG> server-cert.csr server-key.pem

OG> Dump content::

OG> $ openssl req -text -noout -in server-cert.csr
OG> ...
OG> $ openssl pkey -text -noout -in server-key.pem
OG> ...

OG> To fill subject automatically::

OG> $ openssl req -sha256 -days 1000 -nodes -newkey rsa:4096 -subj
OG> "/C=UA/ST=User/L=City/O=Corp/OU=SubCorp/CN=myvps.com" -keyout server-key.pem
OG> -out server-cert.csr


OG> Prepare use minimal ``openssl.cnf``::

OG> [ ca ]
OG> default_ca = CA_default

OG> [ CA_default ]
OG> new_certs_dir = .
OG> database = index.txt
OG> serial = serial.txt

OG> default_md = default
OG> policy = policy_anything

OG> [ policy_anything ]
OG> countryName = optional
OG> stateOrProvinceName = optional
OG> localityName = optional
OG> organizationName = optional
OG> organizationalUnitName = optional
OG> commonName = supplied
OG> emailAddress = optional

OG> Prepare some CA database files::

OG> $ echo 01 > serial.txt
OG> $ touch touch index.txt index.txt.attr

OG> Sign server CSR with CA key::

OG> $ openssl ca -days 1000 -config openssl.cnf -cert ca-root-cert.pem -keyfile
OG> ca-root-key.pem -out server-cert.pem -in server-cert.csr

OG> Dump signed server certificate::

OG> $ openssl x509 -text -noout -in server-cert.pem
OG> ...

OG> Copy CA certificate to Debian tructed store::

OG> $ sudo cp ca-root-cert.pem /usr/share/ca-certificates/my/my-ca-root-cert.crt

OG> and register certificate::

OG> $ sudo dpkg-reconfigure ca-certificate

OG> Copy signed server key + certificate to server and resister it::

OG> $ scp server-key.pem server-cert.pem user@vps
OG> $ ssh user@vps
OG> % sudo cp server-cert.pem /etc/ssl/certs/proftpd.crt
OG> % sudo cp server-key.pem /etc/ssl/private/proftpd.key

OG> After all I can run::

OG> $ lftp ftp://us...@myvps.com
OG> lftp us...@myvps.com:~> ls
OG> -rw-r----- 1 ftp ftp 276 Nov 24 20:16 index.html
OG> lftp us...@myvps.com:/> exit

OG> without::

OG> $ lftp -e 'set ssl:verify-certificate no' ftp://us...@myvps.com

OG> Note that ftp:// URL domain name SHOULD match certificate CN name or you get error::

OG> Fatal error: Certificate verification: certificate common name doesn't match
OG> requested host name ‘myvps.com

Тут есть еще такая штука, как X509v3 Subject Alternative Name. У меня, например,

X509v3 Subject Alternative Name:
DNS:nest.lasgalen.net, DNS:jabber.lasgalen.net, DNS:mail.lasgalen.net

В конфиге это задается

subjectAltName=DNS:nest.lasgalen.net,DNS:jabber.lasgalen.net,DNS:mail.lasgalen.net

Сколь я помню, при наличии subjectAltName CN игнорируется (в смысле,
если имя хоста совпадает с CN, но отсутствует в subjectAltName,
сертификат считается непригодным для этого хоста).

Mikhail A Antonov

unread,
Nov 25, 2015, 2:00:03 AM11/25/15
to
24.11.2015 09:01, Artem Chuprina пишет:

> Сделать честно не то чтобы офигительно сложно, но я не знаю простых
> энд-юзерских инструментов для этого. Сам тупо пользуюсь openssl, но я
> этой криптографией занимался профессионально, и понимаю, что делать с
> его ключами и конфигом. А так-то openssl как утилита - штука
> отладочная, для реальной работы не предазначенная. Хотя может.
Можно посмотреть на tinyca. Оно с гуём относительно просто создаёт свой
CA и этим CA подписывает.
На сколько я помню, tinyca не умеет работать с сертификатами на
несколько имён, но т.к. она (программа) является лишь гуём для вызова
openssl - это решаемо.

--
Best regards,
Mikhail
-
WWW: http://www.antmix.ru/
XMPP: ant...@stopicq.ru

signature.asc

Max Kosmach

unread,
Nov 25, 2015, 2:20:03 AM11/25/15
to
25.11.2015 9:53, Mikhail A Antonov пишет:
> 24.11.2015 09:01, Artem Chuprina пишет:
>> Сделать честно не то чтобы офигительно сложно, но я не знаю простых
>> энд-юзерских инструментов для этого. Сам тупо пользуюсь openssl, но я
>> этой криптографией занимался профессионально, и понимаю, что делать с
>> его ключами и конфигом. А так-то openssl как утилита - штука
>> отладочная, для реальной работы не предазначенная. Хотя может.
> Можно посмотреть на tinyca. Оно с гуём относительно просто создаёт свой
> CA и этим CA подписывает.
> На сколько я помню, tinyca не умеет работать с сертификатами на
> несколько имён, но т.к. она (программа) является лишь гуём для вызова
> openssl - это решаемо.

Еще есть простой набор скриптов easy-rsa из openvpn. Есть отдельным пакетом в Debian. В первом приближении самодостаточен и прост в использовании и
легко модифицируется под сови нужды.




--
С уважением,
Космач Максим

Artem Chuprina

unread,
Nov 25, 2015, 3:20:03 AM11/25/15
to
Max Kosmach -> debian-...@lists.debian.org @ Wed, 25 Nov 2015 10:01:43 +0300:

>>> Сделать честно не то чтобы офигительно сложно, но я не знаю простых
>>> энд-юзерских инструментов для этого. Сам тупо пользуюсь openssl, но я
>>> этой криптографией занимался профессионально, и понимаю, что делать с
>>> его ключами и конфигом. А так-то openssl как утилита - штука
>>> отладочная, для реальной работы не предазначенная. Хотя может.
>> Можно посмотреть на tinyca. Оно с гуём относительно просто создаёт свой
>> CA и этим CA подписывает.
>> На сколько я помню, tinyca не умеет работать с сертификатами на
>> несколько имён, но т.к. она (программа) является лишь гуём для вызова
>> openssl - это решаемо.

MK> Еще есть простой набор скриптов easy-rsa из openvpn. Есть отдельным пакетом в
MK> Debian. В первом приближении самодостаточен и прост в использовании и легко
MK> модифицируется под сови нужды.

Тоже, кстати, вариант. Но там, я подозреваю, придется чуть-чуть
поотрывать настройки, сделанные именно под OpenVPN. Хотя, возможно, в
свежих версиях они уже более толковые.

Oleksandr Gavenko

unread,
Nov 25, 2015, 5:10:05 AM11/25/15
to
On 2015-11-25, Artem Chuprina wrote:

> Вот меня в нижеприведенном прям смущает, что конфиг совсем
> минималистичный. openssl нынче что, сам догадывается поставить
> правильное назначение сертификата в зависимости от того, делают его
> самоподписанным или подписывают заявку?

> Можно посмотреть вывод openssl x509 -text -noout этих обоих сертификатов
> в части X509v3 extensions?
>
> У меня для сертификата CA там показывают
>
> X509v3 Basic Constraints:
> CA:TRUE
> X509v3 Key Usage:
> Certificate Sign, CRL Sign
>

X509v3 extensions:
X509v3 Subject Key Identifier:
D2:7C:EB:58:DD:F7:74:EA:01:3F:60:C6:73:D4:40:1F:88:38:96:AA
X509v3 Authority Key Identifier:
keyid:D2:7C:EB:58:DD:F7:74:EA:01:3F:60:C6:73:D4:40:1F:88:38:96:AA

X509v3 Basic Constraints:
CA:TRUE

> а для сертификата сервера
>
> X509v3 Basic Constraints:
> CA:FALSE
> Netscape Cert Type:
> SSL Server
> X509v3 Extended Key Usage:
> TLS Web Server Authentication

Нету секции "X509v3 extensions".

================================================================

В lighttpd всунул сертификат сервера:

$ cat /etc/ssl/private/proftpd.key /etc/ssl/certs/proftpd.crt > /etc/lighttpd/lighttpd.pem

Как отпостил ранее, созданый CA сертификат поместил в хранилище Debian.

curl / wget стали загружать страницы с HTTPS без -k / --no-check-certificate

Я всунул CA сертификат в Iceweasel (через preference -> advanced ->
certificates -> authorities).

Страницы просто сразу открывались (без предложения доверять сертификату
сервера).

--
Best regards!

Oleksandr Gavenko

unread,
Nov 25, 2015, 3:00:03 PM11/25/15
to
On 2015-11-25, Artem Chuprina wrote:

> OG> without::
>
> OG> $ lftp -e 'set ssl:verify-certificate no' ftp://us...@myvps.com
>
> OG> Note that ftp:// URL domain name SHOULD match certificate CN name or you get error::
>
> OG> Fatal error: Certificate verification: certificate common name doesn't match
> OG> requested host name ‘myvps.com
>
> Тут есть еще такая штука, как X509v3 Subject Alternative Name. У меня, например,
>
> X509v3 Subject Alternative Name:
> DNS:nest.lasgalen.net, DNS:jabber.lasgalen.net, DNS:mail.lasgalen.net
>
> В конфиге это задается
>
> subjectAltName=DNS:nest.lasgalen.net,DNS:jabber.lasgalen.net,DNS:mail.lasgalen.net
>

Я помучился что бы получить widlcard в имени домена:

$ openssl req -sha256 -days 1000 -nodes -newkey rsa:4096 -extensions v3_req -subj "/C=UA/ST=User/L=City/O=Corp/OU=SubCorp/CN=myvps.com/emailAddress=in...@myvps.com" \
-reqexts SAN -config <( cat /etc/ssl/openssl.cnf; echo "[SAN]"; echo "subjectAltName = email:copy,DNS:*.myvps.com,DNS:myvps.com" ) \
-keyout http-server-key.pem -out http-server-cert.csr

Для переноса subjectAltName при подписывании нужно добавить немножко в файл
настроек::

[ ca ]
default_ca = CA_default

[ CA_default ]
new_certs_dir = .
database = index.txt
serial = serial.txt

default_md = default
policy = policy_anything
certificatePolicies = policy_anything

x509_extensions = usr_cert
copy_extensions = copy # <== trick to move subjectAltName unchanged or "openssl ca" strip any x509 v3 extensions

[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# subjectAltName = supplied

[ usr_cert ]

basicConstraints=CA:FALSE
nsCertType = server

Подпись выполняется той же последовательностью:

$ openssl ca -days 1000 -config openssl.cnf -cert ca-root-cert.pem -keyfile ca-root-key.pem -out http-server-cert.pem -in http-server-cert.csr

Пробовал задавать патерны DNS: через переменную окружения, добавив настройку в
блок "[usr_cert]":

subjectAltName=${ENV::sanvar}

Но по:

$ env sanvar='DNS=myvps.com' openssl ca -days 1000 -config openssl.cnf -cert ca-root-cert.pem -keyfile ca-root-key.pem -out http-server-cert.pem -in http-server-cert.csr

получал ошибку:

Error Loading extension section usr_cert
139621097580176:error:0E06D06C:configuration file routines:NCONF_get_string:no value:conf_lib.c:324:group=CA_default name=email_in_dn
139621097580176:error:2207507C:X509 V3 routines:v2i_GENERAL_NAME_ex:missing value:v3_alt.c:531:
139621097580176:error:22098080:X509 V3 routines:X509V3_EXT_nconf:error in extension:v3_conf.c:95:name=subjectAltName, value=DNS=myvps.com

Эксперименты показали что такая запись работает:

subjectAltName = email:copy,DNS:${ENV::sanvar}

Я полагаю что подстановка выполняется после парсинга файла и вводить
синтаксическую структуру через подстановку переменной - нельзя. Хотя в блогах
есть примеры, в которых приводится указанная конструкция - т.е. это зависит от
версии openssl.

Но т.к. заранее не знаешь число DNS: параметров - лучше работать через трюк с
"<(...)" в Bash.

Я хотел добится того что openssl.cnf был неизменямым и домены/адреса
поставлялись через аргументы.

Сформированый подписаный сертификат позволил открывать страницы myvps.com и
blog.myvps.com без ругани о недоверенном сертификате (при условии что
ca-root-cert.pem проимпортирован как доверенный).

> Сколь я помню, при наличии subjectAltName CN игнорируется (в смысле,
> если имя хоста совпадает с CN, но отсутствует в subjectAltName,
> сертификат считается непригодным для этого хоста).
>

Вроде так и есть:

http://wiki.cacert.org/FAQ/subjectAltName

subjectAltName must always be used (RFC 2818 4.2.1.7, 1. paragraph). CN is
only evaluated if subjectAltName is not present and only for compatibility
with old, non-compliant software. So if you set subjectAltName, you have to
use it for all host names, email addresses, etc., not just the "additional"
ones.

http://stackoverflow.com/a/5937270/173149

RFC 5280, section 4.1.2.6 says "The subject name MAY be carried in the
subject field and/or the subjectAltName extension". This means that the
domain name must be checked against both SubjectAltName extension and
Subject property (namely it's common name parameter) of the certificate.
These two places complement each other, and not duplicate it. And
SubjectAltName is a proper place to put additional names, such as
www.domain.com or www2.domain.com

Update: as per RFC 6125, published in '2011 the validator must check SAN
first, and if SAN exists, then CN should not be checked. Note, that the RFC
6125 is relatively recent and there still exist certificates and CAs that
issue certificates, which include the "main" domain name in CN and
alternative domain names in SAN. I.e. by excluding CN from validation if SAN
is present, you can deny some otherwise valid certificate.


--
Best regards!

Oleksandr Gavenko

unread,
Nov 25, 2015, 3:10:04 PM11/25/15
to
On 2015-11-25, Oleksandr Gavenko wrote:

> Пробовал задавать патерны DNS: через переменную окружения, добавив настройку в
> блок "[usr_cert]":
>
> subjectAltName=${ENV::sanvar}
>
> Но по:
>
> $ env sanvar='DNS=myvps.com' openssl ca -days 1000 -config openssl.cnf -cert ca-root-cert.pem -keyfile ca-root-key.pem -out http-server-cert.pem -in http-server-cert.csr
>
> получал ошибку:
>
> Error Loading extension section usr_cert
> 139621097580176:error:0E06D06C:configuration file routines:NCONF_get_string:no value:conf_lib.c:324:group=CA_default name=email_in_dn
> 139621097580176:error:2207507C:X509 V3 routines:v2i_GENERAL_NAME_ex:missing value:v3_alt.c:531:
> 139621097580176:error:22098080:X509 V3 routines:X509V3_EXT_nconf:error in extension:v3_conf.c:95:name=subjectAltName, value=DNS=myvps.com
>
> Эксперименты показали что такая запись работает:
>
> subjectAltName = email:copy,DNS:${ENV::sanvar}
>
> Я полагаю что подстановка выполняется после парсинга файла и вводить
> синтаксическую структуру через подстановку переменной - нельзя. Хотя в блогах
> есть примеры, в которых приводится указанная конструкция - т.е. это зависит от
> версии openssl.
>
> Но т.к. заранее не знаешь число DNS: параметров - лучше работать через трюк с
> "<(...)" в Bash.

Затупил, в синтаксисе напутал, если поставить знак ":" - то работает:

$ env sanvar='DNS:myvps.com,DNS:*.myvps.com' openssl ca ...

--
Best regards!
0 new messages