-
Notifications
You must be signed in to change notification settings - Fork 323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Revisit running openfortivpn as root? #650
Comments
In any case it is till true that the
|
Instead let's try whether modifying |
I can confirm that
After:
@zez3 On the other hand I don't think we want to follow that path:
We could perhaps revert ff290d1 to a mere warning when openfortivpn is not run as root. We would then have this warning:
and this error from pppd which lacks precision:
Then we would also need an option to remove Am I missing something? |
I agree, this root permission does not bother me much at this time. |
@adrienverge What was the rationale behind using the I have found some PPP C code, although I have no clue at this point if it can replace Some of these projects might be small enough to be added as a dependency to openfortivpn. Perhaps we can get rid of the authentication part without too much work. It looks like PPP support in C is ~ 1000 lines of code. |
Either they didn't exist, or I wasn't aware of them. If they now exist and work, they could be a solution. |
But why do we need it in the first place? L2 frame HDLC encapsulation is just non-sense for me. It must be a good reason for all this...Perhaps NAT-traverse or something like that? |
@zez3 I really don't know. Isn't PPP encapsulation enforced by the SSL-VPN portal? Do we really have a choice here? |
I see that we open an SSL connection, some HTTP negotiation happens, we ask the gateway to start tunnelling, and I/O between pppd and the gateway is initiated: Line 1036 in 5d0a8ab
I haven't seen code anywhere that would initiate PPP on our side. PPP just happens or so it seems to me. @zez3 What I mean to say is that I am unable find an alternative myself, not that an alternative doesn't exist. I'm not good at networking and I am open to suggestions. @adrienverge Do you recall whether PPP is enforced by the VPN gateway? Are there any alternatives to PPP, such as the TUN interface suggested by @zez3? |
I'm sorry, I don't know :/ |
I believe we don't have a choice here. ppp with hdlc encoding is just how it is implemented on the server side, at least that's my understanding, but I may be wrong |
FWIW in OpenConnect we've been looking at the F5 BIG-IP SSL-VPN support. That's PPP-based too, and always used to have HDLC but now has an option for running without HDLC. We're adding PPP support to OpenConnect — I was a little dubious but since it we only need really basic LCP and IPCP/IP6CP without all the bells and whistles that pppd supports, I think it's OK. https://gitlab.com/dlenski/openconnect/commits/f5 It means we can run the client completely as a non-root user. For all the other protocols, NetworkManager already runs it like that; even setting up the tun device for it in advance so it doesn't even need privs to do that. http://www.infradead.org/openconnect/nonroot.html It'd be really interesting to look at expanding to support FortiVPN in OpenConnect too. @adrienverge, @DimitriPapadopoulos how would you feel about maintaining that? |
What @dwmw2! Integrating into OpenConnect has so many advantages that reduce the tedium of dealing with boilerplate issues in VPN clients, as I wrote about here recently (in regards to the PPP-based protocol which we're currently trying to implement): https://gitlab.com/openconnect/openconnect/-/issues/107#note_336889894 |
It would be nice if someone would be able to demo speed compare the LCP HDLC PPP to the TLS implementations in OpenConnect before or after you actually implement it. I was thinking to do the same with the openfortivpn but I am still thinking at how can I achieve that. (Perhaps I just need to use the Forti Web-Mode Portal) |
@zez3 As far as I can see the FortiGate portal uses PPP and HDLC. It's not our choice. It doesn't make sense to compare TLS vs. PPP and HDLC, openfortivpn does use TLS. |
We have the HDLC mode working in OpenConnect now, doing PPP over HDLC over TLS. It's all in OpenConnect itself without using external pppd. It's still in the 'f5' branch for now; will look at making it merge-ready and CPU-optimising it. This has been tested with the F5 BIG-IP SSL VPN, but we've tried to keep the PPP bits separate from the F5 specifics, so adding a new PPP-based protocol like Fortinet's should be fairly trivial. You'll note that the I'm looking at |
About I had a look at OpenConenct. Just wondering, why don't you re-use existing reference code? For example for HDLC we re-use the reference code directly from RFC 1662, as is. For HTTP and XML parsing I was thinking of using 3rd party code, fast and with a small footprint, that can be included as a mere C file/header (#347), for example PicoHTTPParser for HTTP and Yxml for XML. |
Is there a FortiGate server anywhere I could have a test account on? I can throw up a shell of a 'fortinet' protocol in OpenConnect, cloned from the F5 one, and it really shouldn't take long to make it functional now we have PPP+HDLC working. It'd be really useful to tease out any accidental F5-isms in our PPP code. |
As for the separation between authentication and connection, the sequence of operations can be seen in Lines 1076 to 1083 in 3638986
What happens before is authentication ( ssl_connect() and auth_log_in() ) and what happens after is connection (auth_request_vpn_allocation() , ssl_connect() and the rest). Does this make any sense?
That said I don't think all of the connection phase can or should be outsourced to NetworkManager. Besides note that NetworkManager is not always available, typically on servers. Setting up the TLS/PPP tunnel should not require special privileges as far as I can see (right now it does because of |
Reference code... I try to where I can. I was very annoyed in the early days when none of the existing HTTP libraries really let me have enough control of the underlying SSL connection, so I ended up having to do that part myself. I note ocserv is using the http-parser library... but I also note that that is a constant source of breakage as http-parser breaks its ABI and ocserv stops working. (OK, it's happened twice so maybe constant is an overstatement but that's twice too many) We do use libxml for XML, and other libraries where appropriate. I don't like reinventing the wheel and I was even baulking at PPP for a long time, before I realised that what we're doing here is really only a subset of PPP and it doesn't fit the pppd model particularly well either. |
Authentication happens once. It results in the cookie. Connection can happen more than once. If the underlying network changes (you undock your laptop and move to wireless, or suspend/resume) while the cookie is still valid, or even if there's just a brief network outage or a NAT failure causing the existing connection to stall, then the client can reconnect using the same cookie, and expects to have the same IP addresses and configuration on the VPN tunnel when it does. So the important distinction for me with the |
NetworkManager... right, NM isn't always available, and is never mandatory. It only really sits in the middle, optionally, between the authentication and the connection. Run OpenConnect from the command line, and it can do all at once (but probably needs to be run as root so it can do the network setup). If you run from NetworkManager, or ConnMan, or anything else like that, then the two-phase design lets you run the authentication in the user's session, interactively and with access to their SSL keys etc., and then hand the actual connection over to an unprivileged process, with NetworkManager playing the middle-man, creating the actual tun device for the unprivileged process to use, and actually setting up the IP config on it when it gets the results back (via D-Bus) from openconnect. But yes, it's all optional. Running directly from the command line also works. |
I'm afraid don't know. I've always used |
Specifically for HDLC you might want to use the code from RFC 1662 - unless you have found performance issues? |
Yeah, that's what we'll use for the FCS but we haven't actually done that yet as F5 doesn't care. It doesn't have the actual HDLC bit-stuffing, does it? |
I've pulled in the code from RFC1662 and implemented FCS support. Can't push to gitlab as @dlenski has been forgetting to add signed-off-by, so it's at http://git.infradead.org/users/dwmw2/openconnect.git/commitdiff/8b122363 On the performance front, I suspect calculating the FCS as we pass through the data doing the HDLC (un)escaping is probably a better use of the data cache than doing a second pass just to do the FCS, so I've done that. |
Maybe it will be more simple to run daemon as root and provide control interface for users? Like wpa_supplicant does? |
OpenConnect itself now contains an LGPL-licensed, event-driven, rather-complete implementation of PPP (either with or without HDLC framing) that does not depend on I also wrote some tests to make OpenConnect's PPP implementation talk to |
@Perlovka You're right, however the daemon itself shouldn't need to run as root either, at least for creating the tunnel. Only routing and DNS server changes at the system level require root privileges (as well as running |
The patch provided in #801 can hopefully get rid of |
Just a reminder that I'd love some helping filling out — or at least testing — authentication for Fortinet VPNs over at OpenConnect.
In addition to "getting rid of 😁 |
I now have a fully working Fortinet implementation in OpenConnect, including authentication. Build from this branch (https://gitlab.com/openconnect/openconnect/commits/ppp_protocols) and run like so… openconnect --prot=fortinet [-u USERNAME] fortinet.vpn.server[:port] \
--vvv --dump # for tons of extra logging The good:
The to-do:
|
I can test that. Hopefully somewhere next week.
If that works I am willing and have to make some donations. |
I have tested this code
Got HTTP response: HTTP/1.1 200 OK |
Thanks for testing!
This looks like it'll be reasonably easy to parse and submit. Could you open an issue for us at OpenConnect, @emelenas, so I can ping you there when I have something for you to test? |
Hey guys, this is the openfortivpn repository. We appreciate suggestions from other projects (e.g. ideas on how things can be handled better, example implementations,...), we are open to collaborate, but I think this discussion has moved far away from openfortivpn. Please handle openconnect issues within that project. It's ok, to link them here, if there is some relation to openfortivpn. Thank you. |
Perhaps it would help to have a look at SLiRP and the more recent implemnetation https://github.com/rootless-containers/slirp4netns/blob/master/slirp4netns.1.md#description and how they handle all in userspace |
Note that merging #1048 would go a long way to permit running openfortivpn as non-root. |
After #373 openfortivpn must be run with root privilege. There are multiples reasons for that. It would be worth re-investigating whether there are ways around that, or at least whether dropping root privilege after initial setup is a possibility, for example after spawning pppd.
Spawning pppd
Members of the
dip
group may runpppd
on Linux distributions such as Debian or Ubuntu:Yet openfortivpn requires root privilege because option
noauth
is privileged:Not sure how to work around this is an a generic way - apart from complex solutions such as splitting openfortivpn into multiple pieces of software with root privileges only the one spawning pppd.
Setting routes
The
CAP_NET_ADMIN
capability might be enough for ipv4_set_route() / ioctl():geteuid() == 0
or the current process capabilities with something likeprctl(PR_CAPBSET_READ, CAP_NET_ADMIN)
.Alternatively routes might be handled outside of openfortivpn:
--set-routes=0
/--no-routes
.Name resolution
DNS servers and search domains might be handled outside of openfortivpn:
--set-dns=0
/--no-dns
and--pppd-use-peerdns=0
. Note that NetworkManager-fortisslvpn currently relies on--pppd-use-peerdns=1
to retrieve DNS parameters from openfortivpn, however that is sort of a hack: Add dns suffix information to informative message #636.External links
Online articles of interest:
The text was updated successfully, but these errors were encountered: