yrutschle / sslh

Applicative Protocol Multiplexer (e.g. share SSH and HTTPS on the same port)
https://www.rutschle.net/tech/sslh/README.html
GNU General Public License v2.0
4.51k stars 367 forks source link

Configuring Transparent Proxy on a router #455

Open dpeterson309 opened 1 month ago

dpeterson309 commented 1 month ago

I don't think this is a SSLH issue necessarily. I think I have my firewall configured wrong. However, I can't seem to figure out what I have wrong. I am trying to get sslh-ev working with transparent proxy to my web and ssh server. This is all bare-bones on my debian router. My sslh config looks like this

table ip firewall {

    # master input table. All other inputs jump from here
    chain input {
        type filter hook input priority 0; policy drop;

        # jump to the correct chains based on the interface input
        # Accept all on the loopback interface
        iifname "lo" accept

        # Accept all on the LAN interface
        iifname $LAN counter packets 0 bytes 0 accept

    # accept all new connections on from the lan to here
    meta iif $LAN ip saddr $LANNET ct state new accept

        # Accept all on the VPN interface
        iifname $VPN counter packets 0 bytes 0 accept

    #allow traffic that is already established from any interface
        #ct state vmap {established: accept, related: accept, invalid: drop}
    ct state established,related counter packets 0 bytes 0 accept
    ct state invalid counter packets 0 bytes 0 drop

        # jump to the WAN table for packets inbound from WAN interface
        iifname $WAN counter packets 0 bytes 0 jump input_wan

    }

    # chain for the WAN
    chain input_wan {
        # allow rate-limited ping responses so we can check the status from the internet
        icmp type echo-request limit rate 5/second accept

    # set trace on all packets in this chain
    #tcp dport 443 meta nftrace set 1

        #allow ssh, http, https, and vpn traffic
        ip protocol . th dport vmap {tcp . 22 : accept, tcp . 443 : accept, tcp . 80 : accept, udp . 1194 : accept}

    }
   # debug table. Place debugging rules here
   chain debug {
          type filter hook prerouting priority -300; policy accept;

    tcp dport 4443 meta nftrace set 1
    #tcp sport 1194 meta nftrace set 1

   }

    #forward traffic from wan/lan
    chain forward {
        type filter hook forward priority 0; policy drop;

        #iifname $LAN oifname $WAN ct status dnat accept
        #iifname $LAN oifname $VPN ct status dnat accept
        #iifname $VPN oifname $LAN ct status dnat accept

    iifname $LAN ip saddr 10.80.82.0/24 counter packets 0 bytes 0 accept
    iifname $POD ip saddr 172.30.32.0/24 counter packets 0 bytes 0 accept
    iifname $KUBE ip saddr 10.89.0.0/24 counter packets 0 bytes 0 accept

    iifname $POD ip daddr 10.80.82.0/24 counter packets 0 bytes 0 accept
    iifname $WAN ip daddr 10.80.82.0/24 counter packets 0 bytes 0 accept
    iifname $KUBE ip daddr 10.80.82.0/24 counter packets 0 bytes 0 accept
    iifname $LAN ip daddr 10.80.82.0/24 counter packets 0 bytes 0 accept

    }

    #masquarde packets originating in the LAN headed to the WAN
    chain postrouting {
        type nat hook postrouting priority 100; policy accept;
        oifname $WAN counter packets 0 bytes 0 masquerade

    #podman
    #ip daddr $PODNET counter packets 0 bytes 0 masquerade 
    }

    #marking packets for sslh for transparent mode
    chain output {
        type route hook output priority -150;
        oif $WAN tcp sport {22, 4443} counter mark set 0x4155;
    }
}

I've omitted the variables, but $LAN is my lan interface, $WAN is the wan interface (modem is a dumb pass-through), and my podman networks are subnets. SSH, NGINX, and SSLH are all running bare-metal, not in pods. My SSLH config looks like this

# possible. It should not be used as-is, and probably should
# not be used as a starting point for a working
# configuration. Instead use basic.cfg.

#verbose: true;
numeric: false;
transparent: true;
timeout: 2;
user: "sslh";
#pidfile: "/var/run/sslh/sslh.pid";

# Specify which syslog facility to use (names for your
# system are usually defined in /usr/include/*/sys/syslog.h
# or equivalent)
# Default is "auth"
syslog_facility: "auth"; 
verbose-probe-error: 3; # failures and problems during probing
verbose-system-error: 3; # system call problem, i.e.  malloc, fork, failing
verbose-int-error: 3; # internal errors, the kind that should never happen
verbose-config-error: 3;  # print configuration errors
verbose-connections: 3; # trace established incoming address to forward address
verbose-connections-error: 3; # connection errors

# List of interfaces on which we should listen
# Options:
listen:
(
    { host: "XXX.XXX.XXX.XXX"; port: "443"; }
);

# List of protocols
#
# Each protocol entry consists of:
#   name: name of the probe. These are listed on the command
#   line (ssh -?), plus 'regex' and 'timeout'.

#   service: (optional) libwrap service name (see hosts_access(5))
#   host, port: where to connect when this probe succeeds
#   log_level:  0 to turn off logging
#               1 to log each incoming connection
#   keepalive:  Should TCP keepalive be on or off for that
#               connection (default is off)
#   fork: Should a new process be forked for this protocol?
#         (only useful for sslh-select)
#
#  Probe-specific options:
# (sslh will try each probe in order they are declared, and
# connect to the first that matches.)
#
#       tls:
#               sni_hostnames:  list of FQDN for that target
#               alpn_protocols: list of ALPN protocols for that target, see:
#               https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
#
#               if both sni_hostnames AND alpn_protocols are specified, both must match
#
#               if neither are set, it is just checked whether this is the TLS protocol or not
#
#               Obviously set the most specific probes
#               first, and if you use TLS with no ALPN/SNI
#               set it as the last TLS probe
#       regex:
#               regex_patterns: list of patterns to match for
#               that target.
#   
# You can specify several of 'regex' and 'tls'.

protocols:
(
     { name: "ssh"; service: "ssh"; host: "10.80.82.1"; port: "22"; keepalive: true; fork: true; log_level: 1;},

#Let's Encryptrypt (tls-sni-* challenges)
# { name: "tls"; host: "localhost"; port: "443"; sni_hostnames: [ "*.*.acme-" ];  log_level: 0;},
     # {name: "tls"; host: "10.80.82.1"; port: "4443"; alpn_protocols: ["acme-tls/1"]; fork: true; log_level: 1;},

# catch anything else TLS
     { name: "tls"; host: "10.80.82.1"; port: "4443"; fork: true; log_level: 3;}

# Regex examples -- better use the built-in probes for real-world use!
# OpenVPN
#     { name: "regex"; host: "10.80.82.1"; port: "1194"; regex_patterns: [ "^\x00[\x0D-\xFF]$", "^\x00[\x0D-\xFF]\x38" ]; }

# Catch-all
#     { name: "regex"; host: "localhost"; port: "443"; regex_patterns: [ "" ]; },

# Where to connect in case of timeout (defaults to ssh)
#     { name: "timeout"; service: "daytime"; host: "localhost"; port: "daytime"; }
);

# Optionally, specify to which protocol to connect in case
# of timeout (defaults to "ssh").
# You can timeout to any arbitrary address by setting an
# entry in 'protocols' named "timeout".
# This enables you to set a tcpd service name for this
# protocol too.
#on-timeout: "timeout";

where XXX.XXX.XXX.XXX is the IP of my WAN interface. When I try to access my server from the WAN interface with

curl -vvv -kl https://my_host_name.com/

I get an initial connection and then curl hangs. I get a bunch of repeated lines in the sslh logs

forward to tls failed:connect: connection timed out

If i use the interface 10.80.82.1:4443 directly from curl, I am able to connect to the web server. This is what makes me believe it is a firewall issue as sslh seems to be taking the connection and trying to forward it. The webserver seems to be running properly. I have been looking at this for several weeks and cannot seem to find my error. Any ideas what is wrong? If I get rid of transparent proxying it does work. However, that makes it hard to log for my web server

ftasnetamot commented 1 month ago

First: You write about sslh config, but you are showing as first file your firewall configuration. For an easy setup of sslh not a single firewall rule is needed. Next: You sslh configuration in the next file contains more comments, than configuration. If you wish, that people are looking to it, please remove all unneeded lines. Makes life easier.

Have you read this and this

As I see no routing configuration in your docu?