headscale-ui icon indicating copy to clipboard operation
headscale-ui copied to clipboard

HAProxy over OPNSense - how to set it up?

Open vampywiz17 opened this issue 3 years ago • 4 comments

Hello there!

Here my config:

version: '3.5'
services:
  headscale:
    image: headscale/headscale:latest-alpine
    container_name: headscale
    volumes:
      - type: bind
        source: /home/vamp/headscale/container-config
        target: /etc/headscale
      - type: bind
        source: /home/vamp/headscale/container-data/data
        target: /var/lib/headscale

    ports:
      - 16666:8080
    command: headscale serve
    restart: unless-stopped
  headscale-ui:
    image: ghcr.io/gurucomputing/headscale-ui:latest
    restart: unless-stopped
    container_name: headscale-ui
    ports:
      - 16667:80

I use OPNSense firewall with HAProxy.

Here the settings:

Set two backend, one of assign to my docker host port 16666, the other to the 16667. I create one Frontend (TLS certificated) on my firewall port 443. Create conditions and rules, that this domain names redirect to the correct backend:

  • https://headscale.mydomain.org:443
  • https://headscale-ui.mydomain.org:443

it work well, i access both site. The problem is the CORS ... i never set it up with HAproxy and not found any documentation that fit to HAProxy plugin with OPNSense (only "vanilla" HAproxy)

So anybody successfully set it up above similar configuration on OPNSense?

vampywiz17 avatar Aug 14 '22 14:08 vampywiz17

Never used HAProxy before, wouldn't even know where to begin. I'll leave this open for a while in case a third someone wants to come along and enlighten us. quick google talks about enabling a lua module which doesn't sound friendly.

You would most likely be better off serving headscale ui on the same subdomain as headscale using the web path. Same domain means no CORS. HAProxy's documentation describes how to do that here.

routerino avatar Aug 14 '22 22:08 routerino

@routerino

Ahhh it added me a idea! i tried it before on same subdomain, but i use more subdomains with same frontend (not only headscale) and it do a bit difficult. But now i split it each other (headcale and ui vs everything else) and now it work well!

Thanks!

PS: it seems someting wrong, because i can't do of things on UI. i can not create name, and can not add a new machine with normal auth. method. If i add it via CLI i see it on UI (namespace and also devices) So a bit weird...

But i able to delete devices, so i think i able to write it to my headscale.

vampywiz17 avatar Aug 15 '22 00:08 vampywiz17

@routerino

Hmm seems it is browser problem.. My home Windows PC (Chrome) affect above problems, but my Linux desktop (also Chrome) work well... Interesting...

vampywiz17 avatar Aug 15 '22 10:08 vampywiz17

this config work well with HAproxy (same domain). I write it here, that possible to help someone:

# Frontend: general_https_frontend ()
frontend general_https_frontend 
    bind headscale.domain.org:443 name headscale.domain.org:443 ssl  crt-list /tmp/haproxy/ssl/5e6986bca1fdf9.68580069.certlist 
    mode http
    option http-keep-alive
    default_backend opnsense
    # tuning options
    timeout client 30s

    # logging options
    # ACL: headscale
    acl acl_62fa39a1c4f969.44775481 path_beg -i /web
    # ACL: headscale_domain_use
    acl acl_62f62cb5c7c7c9.95836142 hdr(host) -i headscale.domain.org
    # ACL: headscale-ui
    acl acl_62f90fb56e8189.73521649 path_beg -i /web

    # ACTION: headscale
    use_backend headscale if !acl_62fa39a1c4f969.44775481 acl_62f62cb5c7c7c9.95836142
    # ACTION: headscale-ui
    use_backend headscale-ui if acl_62f90fb56e8189.73521649 acl_62f62cb5c7c7c9.95836142

# Backend: headscale ()
backend headscale
    # health checking is DISABLED
    mode http
    balance source
    # stickiness
    stick-table type ip size 50k expire 30m  
    stick on src
    # tuning options
    timeout connect 30s
    timeout server 30s
    http-reuse safe
    server headscale 192.168.31.105:16666 

# Backend: headscale-ui ()
backend headscale-ui
    # health checking is DISABLED
    mode http
    balance source
    # stickiness
    stick-table type ip size 50k expire 30m  
    stick on src
    # tuning options
    timeout connect 30s
    timeout server 30s
    acl auth_ok http_auth(list_62f90f8e3b26e5.68322732)
    http-request auth if !auth_ok
    http-reuse safe
    server headscale-ui 192.168.31.105:16667 

I use 3 conditions and 2 rules.

  1. conditon: domain path start with /web
  2. conditon: domain path NOT start with /web (negate the previous condition)
  3. condition: domain name is headscale.domain.org (it need, because i use more sub-domains)

1 rule: 1 + 3 condition with AND logical and attach it to headscale-ui IP+port backend 2 rule: 2 + 3 condition with AND logical and attach it to headscale IP+port backend

both headscale and headscale-ui is plain http, without encryption, the HAproxy do the SSL part. It no problem that is available without encryption in local network. The point is that is only accessable via SSL from the web.

+1

because (if i look right) headscale-ui not contain any authentication, i set a basic one with HAProxy.

vampywiz17 avatar Aug 15 '22 14:08 vampywiz17

closing for now, I'll link this issue in the doco if we get any other HAproxy related questions.

Note that there is no auth (correct), but all secrets are saved locally to the browser. It's not like putting in the API key lets anyone manipulate the platform.

routerino avatar Aug 17 '22 23:08 routerino