omar-polo / gmid

a Gemini server
https://gmid.omarpolo.com
ISC License
102 stars 7 forks source link

Reverse proxy support #7

Closed rdelaage closed 2 years ago

rdelaage commented 2 years ago

Hi!

My gemini server does not support TLS shutdown and this feature will probably be mandatory in the future, so I am considering to change for an other gemini server. The only thing I need is support for virtual hosts, statics files and reverse proxy. Gmid seems to be a great choice but I'm not sure for the support of reverse proxy, is it supported or planned ? If this is not planned could it be easily added ?

omar-polo commented 2 years ago

Hello :)

Yes, I'm planning to add a proxy capability in the next release. I did some refactoring to simplify the addition but haven't still actually implemented it yet.

omar-polo commented 2 years ago

it took me a while, but I just added it to the master branch. The current syntax is

server "example.com" {
    # ...
    proxy relay-to host:port
}

but it's better documented in the man page. There isn't any option available yet, but I'm planning to add some (for the certificates at least); the bulk of the work is done tho :)

omar-polo commented 2 years ago

oh, forgot to say, I just completed it today so it may have still some bugs here and there, use with care :)

I'll tag a release once I'm sure it's solid and I've implemented a few more things on top of this.

Cheers!

rdelaage commented 2 years ago

Oh, it's very cool 😄 I will test that as soon as possible

rdelaage commented 2 years ago

Hi, I just switched to gmid. I couldn't get the proxy to work.

I just have something like

server "example.com" {
    cert "/path/to/cert"
    key "/path/to/key"

    proxy relay-to localhost:1966
}

I just get a log saying there is a syntax error :(.

Maybe I am missing something ? Is there an other mandatory option ?

omar-polo commented 2 years ago

Yeah, I changed slightly the syntax to accommodate for some further options:

server "example.com" {
    cert "..."
    key "..."

    proxy {
        relay-to localhost:1966
    }
}

(further options are documented in the man page)

rdelaage commented 2 years ago

Ho, it's that. Thank you very much!

omar-polo commented 2 years ago

just to clarify: when features are added during the development cycle for a version it can happen that the syntax and/or options for it change quickly. Once I start to feel confident about such thing, I tag a release and then I avoid to change the syntax or the options to not break existing setups.

in this case i've tweaked the syntax shortly after merging it in the master branch, now that it's present in a release (1.8) it's unlikely to change.

Cheers!

norayr commented 8 months ago

hello, i am trying to use this reverse proxy functionality.

compiled latest gmid from git.

i have molly brown which listens on 1966.

this is my conf file.

server "example.am" {
    listen on * port 1965
    cert "/srv/gemini/example.am/example.am.cer"
    key "/srv/gemini/example.am/example.am.key"

    # Proxy pass to another gemini server
    proxy {
    #sni "example.am"

    #cert "/srv/gemini/example.am/example.am.cer"
    #key "/srv/gemini/example.am/example.am.key"

        relay-to localhost:1966
    }
}

i run gmid with

/opt/gmid/bin/gmid -c test.conf -f -v

and i get on the console this output from gmid:

debug: ecdsae_do_sign
replying to server #2
handshake: SNI: "example.am"; decoded: "example.am"; matched: "example.am"
opening proxy connection for localhost:1966:1965
getaddrinfo("localhost:1966", "1965"): Name or service not known
<client_ip>:4910 GET gemini://example.am/ 43 proxy error

i see the proper certificate in the browser, but i get 'proxy error' in lagrange though the certificate is correct. you can see i also tried to add some options and commented them, this didn't help.

of course accessing example.com:1966 works.

i also tried to use configuration options: proxy for-host "example.am:1966" or for-host "example.am:1965" or for-host "example.am" but with that i was getting was:

GET gemini://example.am/ 51 not found
omar-polo commented 8 months ago

@norayr I changed slightly the syntax after the first draft I was showing here. The correct syntax is in your case should be:

server "example.com" {
    listen on * port 1965
    cert "/path/to/cert"
    key "/path/to/key"

    proxy {
        relay-to localhost port 1966
    }
}

The last example of the gmid.conf(5) manpage shows exactly this kind of setup.

However I admit that the error message

getaddrinfo("localhost:1966", "1965"): Name or service not known

is probably not the clearest (here it's failing to resolve the host localhost:1966 as an IP address, I'll try to improve the logs for this kind of failures.

Thanks,

norayr commented 8 months ago

good, it worked!

however i was getting

handshake with proxy failed: name `localhost' not present in server certificate

:13459 GET gemini://example.am/ 43 handshake failed then i solved it by adding ``` verifyname off ``` in the config. now it works! thank you for this feature. this makes gmid universal gemini server. i can host several vhosts and i can also redirect to services like bbs or tootik.
omar-polo commented 8 months ago

@norayr Another way is to use the sni option, but in the context of relaying another server running on localhost the difference hardly matters.

does tootkit works behind gmid? I'm curious to try it out but haven't had the time yet ^^"

norayr commented 8 months ago

i think i will try soon, and let you know.