3 điểm bởi GN⁺ 2023-12-25 | 1 bình luận | Chia sẻ qua WhatsApp
  • Ngay cả khi cổng SSH bị chặn trong mạng bị hạn chế, vẫn có thể tạo đường truy cập từ xa qua cổng HTTPS 443 và phương thức CONNECT
  • Trên máy chủ, mở CONNECT bằng mod_proxy_connect của apache2, nhưng chỉ cho phép đích ssh-server:22 để thu hẹp phạm vi proxy
  • Ở phía client, kết hợp ProxyCommand của OpenSSH với socat, còn với HTTPS thì script sẽ tự gửi trực tiếp header CONNECT
  • Một số tường lửa hoặc httpd có thể đóng kết nối nhàn rỗi, nên dùng ServerAliveInterval 30 để hỗ trợ duy trì phiên
  • Cách này bọc SSH bên trong TLS nên dễ tránh bị chặn hơn, nhưng vẫn có nhược điểm là mã hóa kép và tăng gánh nặng cấu hình phía client

Tạo đường kết nối SSH trong mạng bị hạn chế

  • Trong môi trường Wi‑Fi bệnh viện, hầu hết các kiểu kết nối đều bị chặn, chủ yếu chỉ cho phép HTTP trên TCP 80HTTPS trên TCP 443
  • DNS trên UDP 53DoT trên TCP 853 dường như hoạt động với các nhà cung cấp DNS phổ biến
  • SSH trên TCP 22 và phần lớn các cổng tùy chỉnh đều bị chặn hoàn toàn
  • Có sẵn kết nối thay thế GSM để cấu hình lại máy chủ từ xa, nên có thể thử nhiều cách vượt chặn khác nhau

Chia sẻ một cổng và đóng gói giao thức

  • Có cách nhận đồng thời SSHHTTPS trên cùng một cổng rồi phân nhánh một cách trong suốt
    • sslh project dùng heuristic để suy đoán giao thức rồi chuyển hướng đến backend thực như SSH, HTTPS hoặc các giao thức được hỗ trợ
    • Ưu điểm là client ssh không cần cấu hình đặc biệt, chỉ cần chỉ định cổng không mặc định
    • Nhược điểm là phải thiết lập thêm dịch vụ, HTTPS cũng phải đi qua sslh, và địa chỉ nguồn của kết nối có thể bị che ở backend nên gây bất tiện cho việc ghi log
  • Một lựa chọn khác là đóng gói hoàn toàn một giao thức bên trong giao thức khác
    • ProxyCommand của OpenSSH cho phép người dùng chỉ định phương tiện truyền tải mà giao thức ssh sẽ sử dụng
    • SSH được bọc trong một luồng khác mà không cần heuristic, phần mềm DPI có thể khó chặn hơn
    • Bản thân HTTPS sẽ không bị chuyển hướng hay ảnh hưởng
    • Đổi lại, mã hóa kép có thể làm giảm hiệu năng và cần cấu hình ở phía client

Cấu hình SSH over HTTP

  • Trước tiên thử cách cho SSH đi qua HTTP
  • Cấu hình apache2 phía máy chủ nạp mod_proxy_connect và cho phép CONNECT tới cổng 22 bằng AllowCONNECT 22
  • <Proxy *> mặc định từ chối tất cả, chỉ cho phép <Proxy ssh-server> để giới hạn đích vào ssh-server:22
  • Ở phía client, .ssh/config dùng ProxyCommand với PROXY:http-server:%h:%p,proxyport=80 của socat
  • Với cấu hình này, chạy $ ssh ssh-via-http sẽ kết nối được tới SSH qua cổng 80
  • ServerAliveInterval 30 sẽ gửi probe định kỳ để tránh trường hợp kết nối HTTP nhàn rỗi bị đóng âm thầm ở giữa đường
  • httpd mặc định dùng TimeOut 60, đóng đường hầm nếu không có vào/ra dữ liệu trong 60 giây

Cấu hình SSH over HTTPS

  • socat dường như không hỗ trợ proxy HTTPS qua phương thức CONNECT, mà chỉ hỗ trợ HTTP
  • Thay vào đó, dùng tính năng bọc TLS của socat, còn yêu cầu dựa trên CONNECT sẽ được tự triển khai trong script
  • ~/.ssh/https-tunnel.bash hoạt động theo luồng sau
    • Trước tiên xuất header CONNECT ssh-server:22 HTTP/1.1Host: ssh-server
    • Sau đó nối nguyên trạng dữ liệu từ đầu vào chuẩn
    • Chuyển toàn bộ luồng sang socat - "SSL:$3:$4" để tạo kết nối TLS
  • Trong .ssh/config, với Host ssh-via-https thì chỉ định ProxyCommand ~/.ssh/https-tunnel.bash
  • Khi chạy $ ssh ssh-via-https, kết nối tới ssh-server qua đường hầm HTTPS hoạt động đúng như mong đợi

Những điểm cần lưu ý khi vận hành

  • Trong môi trường cho phép HTTPS rộng rãi, cách này có thể truyền dữ liệu xuyên qua các thiết bị trung gian rất hạn chế
  • Phương thức CONNECT trông như một di tích cũ, nhưng vẫn hữu ích để bọc luồng payload TCP tùy ý bên trong luồng host TLS
  • ServerAliveInterval giúp duy trì kết nối OpenSSH khi tầng truyền tải bên dưới không thân thiện với các kết nối nhàn rỗi
  • Một biến thể cấu hình nginx có tại CONNECT passthrough on nginx

1 bình luận

 
GN⁺ 2023-12-25
Ý kiến trên Hacker News
  • Đoạn trong bài viết nói rằng “HTTPS có ở khắp mọi nơi nên ngay cả các thiết bị trung gian bị giới hạn nặng nề cũng có thể cho dữ liệu đi qua” chính là lý do gần như mọi giao thức VPN độc quyền, cái gọi là “SSL VPN”, đều triển khai chế độ tạo tunnel qua HTTPS
    Dù không phải hành vi mặc định thì ít nhất chúng cũng có một đường thay thế, nhằm bảo đảm có một chế độ hoạt động được trên gần như mọi kết nối Internet trên toàn thế giới
    Tôi là một trong những nhà phát triển chính của https://gitlab.com/openconnect/openconnect, dự án triển khai nhiều giao thức VPN dựa trên TLS, và cũng đã tạo ra https://github.com/dlenski/what-vpn để phát hiện và nhận diện thêm nhiều loại máy chủ VPN dựa trên TLS

    • Thật đáng tiếc khi những nỗ lực nhằm giới hạn thô bạo tính hữu dụng của kết nối lại khiến việc dùng đúng mục đích vốn có của cổng trở nên khó khăn
  • Ngày trước nhà cung cấp Internet Hà Lan XS4ALL từng cung cấp đúng kiểu tính năng này
    Họ mở SSH trên cổng 80, và điều đó đã giúp tôi vài lần khi đi du lịch, lúc WiFi khách sạn chặn mọi thứ ngoài cổng 80

    • XS4ALL rất tuyệt, và thật đáng tiếc khi KPN quyết định xóa sổ thương hiệu đó
      Tuy vậy, đứng từ phía KPN thì có lẽ văn hóa hacker của XS4ALL vốn dĩ không phải điều họ thấy thoải mái
    • Tôi từng là người dùng XS4ALL, nó thực sự rất tuyệt, và có tinh thần Internet thời kỳ đầu
      Nó tạo cảm giác như sự tái hiện của văn hóa radio cướp sóng thập niên 1960
      https://en.wikipedia.org/wiki/Pirate_radio_in_Europe
    • Trong các cổng không chuẩn dành cho SSH, cổng 443 nằm khá cao trong danh sách
      https://www.shodan.io/search/facet?query=ssh&facet=port
      https://www.shodan.io/search/facet.png?query=ssh&facet=port
      Trong khi đó cổng 80 thì ít phổ biến hơn nhiều
    • Tôi không biết XS4ALL từng là một nhà cung cấp Internet đầy đủ
      Tôi nhớ trước đây chỉ dùng nó như một nhà cung cấp newsgroup
    • Ở mức độ nào đó, XS4ALL vẫn được tiếp nối dưới hình thức Freedom: https://freedom.nl/en
  • Thường còn có lựa chọn thứ ba: chạy SSH trên cổng 80 hoặc 443 của một máy chủ khác, rồi từ đó dùng ProxyJump đến đích
    Hoặc cũng có thể mở SOCKS qua máy đó để có một kết nối Internet nhìn chung ít bị lọc hơn
    Tôi dùng SOCKS, và còn chuyển tiếp cả DNS dựa trên TLS qua tính năng port forwarding của kết nối SSH
    Vài năm trước khi tôi mới thiết lập SOCKS proxy và dùng WiFi khá thường xuyên, tôi chưa gặp nơi nào kiểm tra vượt quá mức chỉ nhìn cổng, nhưng loại thiết bị đó có tồn tại và giờ có thể đã phổ biến hơn

    • Hồi học lớp 10 tôi vừa mới bắt đầu tự host, và trường chặn website nhưng hoàn toàn không chặn cổng
      Thế là tôi просто SSH vào máy chủ của mình và dùng như bình thường
      Sau đó tôi tạo một kho lưu trữ file Windows .iso, tải về bằng laptop rồi dùng scp đẩy lên máy chủ; có lẽ việc dùng tới hàng chục GB cho cả upload lẫn download trên các cổng không phải 80/443 đủ để kích hoạt kiểm tra lưu lượng, nên đến khoảng giờ ăn trưa bên IT đã chặn cổng 22
      Nhưng họ không chặn các cổng khác, nên tôi chuyển SSH sang 443 trong phần port forwarding và tiếp tục dùng
      Sau đó đội IT của trường phát hiện tôi dùng SSH trên 443 và thêm phân tích lưu lượng cơ bản để chặn SSH trên 80/443, nhưng tất cả các cổng khác vẫn mở
      Cuối cùng họ chặn máy chủ của tôi theo IP, nhưng mọi IP khác vẫn mở
      Có thể vượt qua bằng cách dùng VPS với ProxyJump, nhưng vì đó là chương trình THPT dự bị đại học nên từ năm 11 trở đi tôi hầu như không còn đến trường, thành ra công sức bỏ ra cũng không đáng lắm
      Lần sau nếu quay lại tôi định thử để chứng minh là vẫn làm được, và nếu họ chặn SSH trên mọi cổng thì có thể chạy SSH over HTTPS trên VPS
      Sau khi tốt nghiệp, tôi định xem lại trên WiFi khách xem có thể đi được đến đâu
  • Hơi lộ liễu là quảng bá một chút, nhưng tại Adaptive [1] chúng tôi đang xây dựng hạ tầng bảo mật dữ liệu
    Một trong các sản phẩm cho phép chuyển SSH và nhiều giao thức khác qua HTTP/3 để người dùng có thể kết nối tới cơ sở dữ liệu, máy chủ và các tài nguyên khác chỉ với một cổng outbound duy nhất
    Nó hơi giống kiểu Ngrok nhưng có thể tự host, đồng thời hỗ trợ truy cập không cần mật khẩu hoặc dùng thông tin xác thực tạm thời kèm cơ chế maker-checker
    [1] https://adaptive.live/

  • Trên thực tế, chỉ cần để openssh lắng nghe trên cổng 443 là đã có thể vượt qua phần lớn tường lửa

  • Hay đấy. Kỳ lạ là trước giờ tôi chưa từng nghĩ về phương thức CONNECT như một reverse proxy thay vì forward proxy
    Chỉ là trong trường hợp của tôi, riêng CONNECT vẫn chưa đủ nên tôi đã chạy SSH qua WebSocket để đi xuyên qua proxy công ty
    Proxy đó kiểm tra các kết nối HTTPS bằng CA tùy chỉnh do họ cấp
    Tôi đã vá socat để phục vụ máy chủ SSH của mình dưới dạng WebSocket thông qua Apache, và phía client thì dùng cùng ProxyCommand của OpenSSH
    Tôi vẫn cứ nghĩ là phải đăng bản vá đó lên, nhưng cũng có những lựa chọn khác như websocat

    • Có lẽ vì vậy mà nhiều proxy hay tường lửa doanh nghiệp chặn WebSocket theo mặc định
    • Nghe như vô tình tạo lại huproxy vậy
  • Gần 20 năm trước tôi đã dùng corkscrew[0], một công cụ làm đúng việc này, để chọc thủng tường lửa công ty
    Bản triển khai độc lập và bài viết đều gọn gàng
    0: https://github.com/bryanpkc/corkscrew

    • Theo như tôi hiểu thì corkscrew chỉ hoạt động trong những điều kiện nhất định: bạn phải ở sau một proxy HTTP, và proxy HTTP đó phải hỗ trợ phương thức CONNECT
      Khoảng 20 năm trước, khi tôi làm một hợp đồng ngắn hạn, điều kiện thứ nhất có nhưng điều kiện thứ hai thì không
      May là có công cụ dùng được cả trong trường hợp này, dù tất nhiên cần cấu hình phía máy chủ
      https://github.com/larsbrinkhoff/httptunnel
  • Nhìn chung, đường hầm qua HTTP/2 tỏ ra là một lựa chọn tốt
    Có gRPC[1], một giao thức gọi thủ tục từ xa được xây dựng trên HTTP/2
    HTTP/2 mạnh ở khả năng ghép kênh vì nó tận dụng một kết nối TCP duy nhất để gửi nhận đồng thời nhiều luồng dữ liệu
    Tuy vậy, vì bản thân QUIC đã cung cấp khả năng ghép kênh nên có lẽ không cần dùng HTTP/3
    Về sau, phần lớn liên lạc có lẽ sẽ chuyển sang HTTP/2 mã hóa và QUIC, vì các nhà sản xuất thiết bị trung gian sẽ không ngừng phân biệt đối xử
    Để giảm thiểu thăm dò chủ động[2], có thể sẽ phải phục vụ nội dung HTTP/2·HTTP/3 ngẫu nhiên, thậm chí do AI tạo ra
    [1] <https://grpc.io>
    [2] <https://blog.torproject.org/learning-more-about-gfws-active-...>

    • Tôi không thực sự hiểu vì sao lại phải chồng thêm một giao thức gọi thủ tục từ xa lên trên HTTP
      Bản thân HTTP đã là một giao thức yêu cầu/đáp ứng và về cơ bản có thể dùng cho gọi thủ tục từ xa
      Dù là HTTP 1, 2 hay 3 thì có vẻ cũng không khác biệt lớn
      Bản thân quá trình tiến hóa của giao thức đó cũng hơi đáng ngờ, và có vẻ được thiết kế để tận dụng những thứ không cần thiết trong môi trường gọi thủ tục từ xa
      Về bản chất, nó gần với thứ được thiết kế cho Internet công cộng hơn là cho dịch vụ cục bộ
    • Với SSH thì chỉ có một kết nối duy nhất, và thực tế SSH tự triển khai ghép kênh, nên tôi không thấy rõ lợi ích của HTTP/2
    • HTTP/2 vẫn là TCP nên vẫn gặp TCP head-of-line blocking
      HTTP/3 chạy trên QUIC
  • Ngược lại, tôi thích HTTP trên SSH hơn
    Nói nửa đùa nửa thật, nhưng sẽ rất tuyệt nếu trình duyệt có sẵn cơ chế quản lý danh tính tương đương SSH
    Lần đầu đọc về hobo, một đề xuất xác thực HTTP bằng khóa công khai, tôi đã rất hào hứng, nhưng rồi nhận ra không có triển khai máy chủ cũng không có triển khai client cho trình duyệt
    Có một bản triển khai bằng JavaScript, nhưng không phải theo kiểu tôi mong muốn

    • ssh -D “*:8080” host
      Lệnh này dựng một proxy SOCKS trên cổng 8080
      Tôi luôn dùng nó trong Firefox, và nó hoạt động như một kiểu VPN đời đầu
      Nó tiện cho cả những mục đích mờ ám, nhưng tôi cũng dùng nó để truy cập dashboard rmq trong mạng riêng của AWS
    • Chứng chỉ client HTTPS thì sao?
      https://techcommunity.microsoft.com/t5/iis-support-blog/clie...
      Tôi không hiểu đủ sâu để biết nó có phù hợp với yêu cầu hay không, nhưng hồi đại học tôi từng dùng nó cho xác thực máy chủ
    • Ý bạn là passkey phải không?
    • Giá mà trong trình duyệt có thể dùng ssh://google.com thì hay biết mấy
    • Nếu bạn bỏ lỡ tuần trước thì đã có một bài viết theo hướng tương tự: SSH3, SSHv2 dùng HTTP/3 và QUIC
      https://news.ycombinator.com/item?id=38664729
  • Sao sslh lại không được yêu thích hơn?
    Nó phát hiện được HTTP, TLS/SSL (bao gồm SNI và ALPN), SSH, OpenVPN, tinc, XMPP, SOCKS5, và còn có thể nhận diện các giao thức khác có thể kiểm tra bằng biểu thức chính quy
    Cách dùng điển hình là phục vụ nhiều dịch vụ cùng lúc trên cổng 443
    Ví dụ, bạn có thể kết nối SSH từ bên trong tường lửa công ty mà vẫn tiếp tục phục vụ HTTPS trên cùng cổng đó
    https://www.rutschle.net/tech/sslh/README.html

    • Nửa đầu bài viết thực ra là nói về việc chọn sslh hay bao bọc hoàn toàn
      Lý do chọn bao bọc hoàn toàn có vẻ là bớt phải cấu hình thêm một dịch vụ, máy chủ HTTP sẽ xử lý kết nối nên địa chỉ từ xa trong log sẽ chính xác, và có lẽ cũng vì tinh thần hacker thích giải pháp mới hơn giải pháp sẵn có