Haproxy для SSH на основі проксі


11

У мене хост-машина з кількома lxc-контейнерами. Я намагаюся надати ssh доступ до контейнерів безпосередньо на основі доменних імен. Для цього я спробував налаштувати HAProxy. Це можна легко досягти за допомогою ACL в режимі http. Коли я спробую те ж саме з режимом tcp для ssh на основі acls, я не в змозі досягти прямого доступу ssh до контейнерів. Далі йде фрагмент, який я використовую в haproxy.cfg.

listen SSHD :2200
    mode tcp
    acl is_apple hdr_dom i apple
    acl is_orange hdr_dom -i orange
    use_backend apple if is_apple
    use_backend orange if is_orange

backend apple
    mode tcp
    server apple 10.0.3.221:22

backend orange
    mode tcp
    server orange 10.0.3.222:22

Де apple.myhost.com та orange.myhost.com - доменні імена для досягнення кожного з контейнерів. HTTP-проксі добре працює з цими acls, але я стикаюся з проблемою трафіку SSH.

Я отримую таку помилку.

ssh_exchange_identification: з'єднання закрите віддаленим хостом

Відповіді:


8

Я використовую екземпляр HAproxy, який працює на pfSense саме для тієї мети, яку ви шукали.

Детальний опис я написав тут: https://julian.pawlowski.me/geeking-out-with-haproxy-on-pfsense-the-ultimate/

Я продовжую цю настройку: порт 443 надається спільним для трафіку SSH, SSL / TLS та OpenVPN, тоді як SSH захищений за допомогою клієнтського сертифіката X.509:

  • нормальний трафік HTTPS (діє як звичайний зворотний проксі для забезпечення веб-трафіку)
  • нормальний трафік HTTPS з автентифікацією сертифікату користувача X509
  • OpenVPN набір трафіку
  • TLS-тунельний трафік SSH, включаючи аутентифікацію сертифікатів користувача X509 (шлюз SSLH)

Це також захищає від сканування портів до точок входу SSH. Крім того, це може допомогти з переходом від IPv4 до IPv6 (і навпаки), гнучким співпрацею та рішеннями для домашніх офісів для адміністраторів тощо.

Я знаю, що там є цей блискучий інструмент SSLH, але це рішення набагато гнучкіше завдяки потужності HAproxy.

Це файл haproxy.cfg, створений pfSense на основі мого допису в блозі для ознайомлення:

global
    maxconn         2000
    stats socket /tmp/haproxy.socket level admin
    uid         80
    gid         80
    nbproc          1
    chroot          /tmp/haproxy_chroot
    daemon
    tune.ssl.default-dh-param   2048
    # Modern browser compatibility only as mentioned here:
    # https://wiki.mozilla.org/Security/Server_Side_TLS
    ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK

    # Time-to-first-Byte (TTFB) value needs to be optimized based on
    # the actual public certificate chain
    # see https://www.igvita.com/2013/10/24/optimizing-tls-record-size-and-buffering-latency/
    tune.ssl.maxrecord 1370

listen HAProxyLocalStats
    bind 127.0.0.1:2200 name localstats
    mode http
    stats enable
    stats admin if TRUE
    stats uri /haproxy_stats.php?haproxystats=1
    timeout client 5000
    timeout connect 5000
    timeout server 5000

frontend HTTP_redirect
    bind            0.0.0.0:80 name 0.0.0.0:80   
    mode            http
    log         global
    option          http-keep-alive
    timeout client      30000
    default_backend     _ssl-redirect_http_ipvANY

frontend LAN_HTTPS
    bind            10.108.2.1:443 name 10.108.2.1:443 ssl no-sslv3 no-tls-tickets no-tlsv10 no-tlsv11 crt /var/etc/haproxy/LAN_HTTPS.pem  
    mode            http
    log         global
    option          http-keep-alive
    option          forwardfor
    acl https ssl_fc
    reqadd X-Forwarded-Proto:\ http if !https
    reqadd X-Forwarded-Proto:\ https if https
    timeout client      30000
    # Remove headers that expose security-sensitive information.
    rspidel ^Server:.*$
    rspidel ^X-Powered-By:.*$
    rspidel ^X-AspNet-Version:.*$
    default_backend     gwsch01_http_ipvANY

frontend WAN_443-merged
    bind            178.26.150.88:443 name 178.26.150.88:443   
    mode            tcp
    log         global
    timeout client      7200000
    tcp-request inspect-delay 5s

    # block SSLv3 as early as possible
    acl sslv3 req.ssl_ver 3
    tcp-request content reject if sslv3
    tcp-request content accept if { req.ssl_hello_type 1 } or !{ req.ssl_hello_type 1 }
    acl         aclusr_custom_req.ssl_hello_type_201    req.ssl_hello_type 1
    acl         aclusr_custom_req.ssl_sni_20-m_20end_20-i_20.ssh.example.com    req.ssl_sni -m end -i .ssh.example.com
    acl         aclusr_custom_req.ssl_sni_20-m_20end_20-i_20.vpn.example.com    req.ssl_sni -m end -i .vpn.example.com
    acl         aclusr_custom_req.len_200   req.len 0
    use_backend     _WAN_HTTPS_tcp_ipvANY if aclusr_custom_req.ssl_hello_type_201 !aclusr_custom_req.ssl_sni_20-m_20end_20-i_20.ssh.example.com !aclusr_custom_req.ssl_sni_20-m_20end_20-i_20.vpn.example.com 
    use_backend     _WAN_HTTPS_auth_tcp_ipvANY if aclusr_custom_req.ssl_hello_type_201 aclusr_custom_req.ssl_sni_20-m_20end_20-i_20.vpn.example.com 
    use_backend     _openvpn_tcp_ipvANY if aclusr_custom_req.len_200 aclusr_custom_req.ssl_hello_type_201 
    use_backend     _WAN_SSLH_tcp_ipvANY if aclusr_custom_req.ssl_hello_type_201 aclusr_custom_req.ssl_sni_20-m_20end_20-i_20.ssh.example.com 
    default_backend     _none_tcp_ipvANY

frontend WAN_HTTPS
    bind            127.0.0.1:2043 name 127.0.0.1:2043 ssl no-sslv3 no-tls-tickets no-tlsv10 no-tlsv11 crt /var/etc/haproxy/WAN_HTTPS.pem  accept-proxy npn http/1.1
    mode            http
    log         global
    option          http-keep-alive
    option          forwardfor
    acl https ssl_fc
    reqadd X-Forwarded-Proto:\ http if !https
    reqadd X-Forwarded-Proto:\ https if https
    timeout client      7200000
    # Remove headers that expose security-sensitive information.
    rspidel ^Server:.*$
    rspidel ^X-Powered-By:.*$
    rspidel ^X-AspNet-Version:.*$
    default_backend     _none_http_ipvANY

frontend WAN_HTTPS_auth-merged
    bind            127.0.0.1:2044 name 127.0.0.1:2044 ssl no-sslv3 no-tls-tickets no-tlsv10 no-tlsv11 crt /var/etc/haproxy/WAN_HTTPS_auth.pem ca-file /var/etc/haproxy/clientca_WAN_HTTPS_auth.pem verify required  accept-proxy npn http/1.1
    mode            http
    log         global
    option          http-keep-alive
    option          forwardfor
    acl https ssl_fc
    reqadd X-Forwarded-Proto:\ http if !https
    reqadd X-Forwarded-Proto:\ https if https
    timeout client      7200000
    # Remove headers that expose security-sensitive information.
    rspidel ^Server:.*$
    rspidel ^X-Powered-By:.*$
    rspidel ^X-AspNet-Version:.*$
    acl         aclusr_host_matches_gwsch01.vpn.example.com hdr(host) -i gwsch01.vpn.example.com
    use_backend     gwsch01_http_ipvANY if aclusr_host_matches_gwsch01.vpn.example.com 
    default_backend     _none_http_ipvANY

frontend WAN_SSLH-merged
    bind            127.0.0.1:2022 name 127.0.0.1:2022 ssl no-sslv3 no-tls-tickets no-tlsv10 no-tlsv11 crt /var/etc/haproxy/WAN_SSLH.pem ca-file /var/etc/haproxy/clientca_WAN_SSLH.pem verify required  accept-proxy npn ssh/2.0
    mode            tcp
    log         global
    timeout client      7200000
    acl         aclusr_custom_ssl_fc_sni_reg_20gwsch01.ssh.example.com  ssl_fc_sni_reg gwsch01.ssh.example.com
    acl         aclusr_custom_ssl_fc_npn_20-i_20ssh_2f2.0   ssl_fc_npn -i ssh/2.0
    use_backend     SSH_gwsch01_https_ipvANY if aclusr_custom_ssl_fc_sni_reg_20gwsch01.ssh.example.com aclusr_custom_ssl_fc_npn_20-i_20ssh_2f2.0 
    default_backend     _none_https_ipvANY

backend _ssl-redirect_http_ipvANY
    mode            http
    timeout connect     30000
    timeout server      30000
    retries         3
    option          httpchk
    redirect scheme https code 301

backend gwsch01_http_ipvANY
    mode            http
    rspadd Strict-Transport-Security:\ max-age=31536000;
    rspirep ^(Set-Cookie:((?!;\ secure).)*)$ \1;\ secure if { ssl_fc }
    timeout connect     3000
    timeout server      7200000
    retries         2
    option          httpchk
    server          gwsch01 127.0.0.1:8443 ssl  verify none 

backend _none_tcp_ipvANY
    mode            tcp
    timeout connect     30000
    timeout server      30000
    retries         3
    option          httpchk OPTIONS / 
    server          none 127.0.0.1:61235 check inter 1000 disabled 

backend _WAN_HTTPS_tcp_ipvANY
    mode            tcp
    timeout connect     30000
    timeout server      7200000
    retries         3
    option          httpchk
    server          WAN_HTTPS 127.0.0.1:2043 check-ssl  verify none send-proxy 

backend _WAN_HTTPS_auth_tcp_ipvANY
    mode            tcp
    timeout connect     30000
    timeout server      7200000
    retries         3
    option          httpchk
    server          WAN_HTTPS_auth 127.0.0.1:2044 check-ssl  verify none send-proxy 

backend _openvpn_tcp_ipvANY
    mode            tcp
    timeout connect     3000
    timeout server      7200000
    retries         2
    option          httpchk
    server          openvpn1 127.0.0.1:1194  

backend _WAN_SSLH_tcp_ipvANY
    mode            tcp
    timeout connect     30000
    timeout server      7200000
    retries         3
    option          httpchk
    server          WAN_SSLH 127.0.0.1:2022 check-ssl  verify none send-proxy 

backend _none_http_ipvANY
    mode            http
    timeout connect     30000
    timeout server      30000
    retries         3
    option          httpchk OPTIONS / 
    server          none 127.0.0.1:61235 check inter 1000 disabled 

backend _none_https_ipvANY
    mode            tcp
    timeout connect     30000
    timeout server      30000
    retries         3
    option          httpchk OPTIONS / 
    server          none 127.0.0.1:61235 check inter 1000 disabled 

backend SSH_gwsch01_https_ipvANY
    mode            tcp
    timeout connect     3000
    timeout server      7200000
    retries         2
    option          httpchk
    server          ssh_gwsch01 127.0.0.1:22

1
Ласкаво просимо до Супер Користувача! Будь ласка, цитуйте основні частини відповіді із посилальних посилань (ив), оскільки відповідь може стати недійсною, якщо змінена пов’язана сторінка.
DavidPostill

1
Де знаходиться остаточна конфігурація HAProxy у цій статті? Я другий @DavidPostill, ви повинні скопіювати основні частини, щоб відповідь була дійсною тут.
Амір

1
Люди, щойно додали довідковий файл.
Юліан Павловський

1

Це неможливо. Протокол HTTP відрізняється, оскільки існує концепція "віртуального хоста", і HAProxy може диференціювати різні хости за допомогою заголовка "Host:". SSH не має нічого подібного, тому хост lxc не може знати контейнер, ви намагаєтесь підключитися.

Але ви можете використовувати ще одну функцію SSH під назвою "Шлюз SSH". Всередині ~/.ssh/authorized_keysє command=варіант. Налаштування фільєрів на основі ключа ssh від вашого lxc-хоста до яблучного та помаранчевого. Потім помістіть ці рядки у authorized_keysфайл lxc :

command="ssh -q -t user@apple $SSH_ORIGINAL_COMMAND" ssh-rsa AAAAsomeB3N...== user@client
command="ssh -q -t user@orange $SSH_ORIGINAL_COMMAND" ssh-rsa AAAAanotherB3N...== user@client

Тепер хост lxs може автоматично підключитися до клієнтського ключа appleта orangeна його основі.

Побачити більше:


0

Боюся, це неможливо. Протокол SSH не підтримує імена хостів. Він просто підключається до IP (після вирішення курсу) і встановлює зашифроване з'єднання. Не існує поняття "віртуальних хостів".

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