ohwgiles/NetworkManager-f5vpn

Can this work with F5 APM Edge

Closed this issue · 6 comments

Hi Oliver,

I found your project on the AUR and left a comment there. I would like to try and get this to work with f5 APM vpn. I note the code says F5 Firepass SSL VPNs. I wonder if there is a great deal of difference?

Your code connects to the remote end for credentials and determines the required ones from the html page etc.

I don't know a great deal about the f5 apm, wondering if the f5 firepass package will work with f5 APM? Let me know if you need any further information to help determine this.

Regards,

I for sure know less than you about APM VPN. If it is really not too different then I'm happy to help implement support for it.

For Firepass SSL VPN it is submitting credentials over HTTPS (some parsing complexity because maybe different fields may be required e.g. OTP), then getting a session ID, then just talking PPP over HTTPS.

On the AUR page you mentioned Endpoint Inspector Application. No idea what that is or what it does, presumably that would have to be figured out and re-implemented. That could range from easy to practically impossible.

Regarding "Unexpected HTTP response code 200" - the Firepass VPN I tested on returns a 302 when you submit credentials if they were accepted. 200 probably means they were denied for whatever reason, maybe missing a credential or some cookie from this Endpoint Inspector. If you are lucky then the content of the response might tell you. Otherwise a good starting point would be to compare the POST made by the web portal that made by this plugin; it can be found in postdata in f5vpn_auth_session_post_credentials.

For development, it's more convenient to use the cli app bundled in this repo (just enable it with ccmake) than the NetworkManager plugin. Once it works with f5vpn-cli it is easy to get it working in NetworkManager.

Done as instructed, i also enabled debug in ccmake. Here is the redacted output

$ /usr1/networkmanager-f5vpn/src/NetworkManager-f5vpn-0.1/f5vpn-cli -h redacted.fqdn -a -c

  • Trying x.x.x.x:443...
  • Connected to redacted.fqdn (x.x.x.x) port 443 (#0)
  • ALPN, offering h2
  • ALPN, offering http/1.1
  • successfully set certificate verify locations:
  • CAfile: /etc/ssl/certs/ca-certificates.crt
  • CApath: none
  • SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
  • ALPN, server did not agree to a protocol
  • Server certificate:
  • subject: C=xx; ST=xxxxxxx; L=xxxxxxx; OU=xxxxxxx; O=xxxxxxxxxxxxxx; CN=redacted.fqdn
  • start date: Nov 25 20:31:02 2020 GMT
  • expire date: Dec 27 20:31:02 2021 GMT
  • subjectAltName: host "redacted.fqdn" matched cert's "redacted.fqdn"
  • issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign RSA OV SSL CA 2018
  • SSL certificate verify ok.

GET / HTTP/1.1
Host: redacted.fqdn
User-Agent: User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
Accept: /

  • Mark bundle as not supporting multiuse
  • HTTP 1.0, assume close after body
    < HTTP/1.0 302 Found
    < Server: BigIP
    < Connection: Close
    < Content-Length: 0
    < Location: /my.policy
  • Added cookie LastMRH_Session="683093fe" for domain redacted.fqdn, path /, expire 0
    < Set-Cookie: LastMRH_Session=683093fe;path=/;secure
  • Added cookie MRHSession="9b35441e20b45f880b452921683093fe" for domain redacted.fqdn, path /, expire 0
    < Set-Cookie: MRHSession=9b35441e20b45f880b452921683093fe;path=/;secure
  • Added cookie MRHSHint="deleted" for domain redacted.fqdn, path /, expire 1
    < Set-Cookie: MRHSHint=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/
    <
  • Closing connection 0
  • Issue another request to this URL: 'https://redacted.fqdn/my.policy'
  • Hostname redacted.fqdn was found in DNS cache
  • Trying 131.242.12.50:443...
  • Connected to redacted.fqdn (131.242.12.50) port 443 (#1)
  • ALPN, offering h2
  • ALPN, offering http/1.1
  • successfully set certificate verify locations:
  • CAfile: /etc/ssl/certs/ca-certificates.crt
  • CApath: none
  • SSL re-using session ID
  • SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
  • ALPN, server did not agree to a protocol
  • Server certificate:
  • subject: C=xxx; ST=xxxxxxxxxxxx; L=xxxxxxx; OU=xxxxxxx; O=xxxxxxxxxxxxx; CN=redacted.fqdn
  • start date: Nov 25 20:31:02 2020 GMT
  • expire date: Dec 27 20:31:02 2021 GMT
  • subjectAltName: host "redacted.fqdn" matched cert's "redacted.fqdn"
  • issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign RSA OV SSL CA 2018
  • SSL certificate verify ok.

GET /my.policy HTTP/1.0
Host: redacted.fqdn
User-Agent: User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
Accept: /
Cookie: LastMRH_Session=683093fe; MRHSession=9b35441e20b45f880b452921683093fe

  • Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    < Server: BigIP
    < Content-Type: text/html; charset=utf-8
    < Accept-Ranges: bytes
    < Connection: close
    < Date: Sun, 17 Jan 2021 09:36:13 GMT
    < Age: 32933
    < Content-Length: 28619
    < X-Frame-Options: DENY
    < Pragma: no-cache
    < Cache-Control: no-cache, must-revalidate
  • Replaced cookie LastMRH_Session="683093fe" for domain redacted.fqdn, path /, expire 0
    < Set-Cookie: LastMRH_Session=683093fe;path=/;secure
  • Replaced cookie MRHSession="57dbe7ab44e95f4076c2c13c683093fe" for domain redacted.fqdn, path /, expire 0
    < Set-Cookie: MRHSession=57dbe7ab44e95f4076c2c13c683093fe;path=/;secure
    <
  • Closing connection 1
    Username: username
    Password:
    Token:
  • Hostname redacted.fqdn was found in DNS cache
  • Trying 131.242.12.50:443...
  • Connected to redacted.fqdn (131.242.12.50) port 443 (#2)
  • ALPN, offering h2
  • ALPN, offering http/1.1
  • successfully set certificate verify locations:
  • CAfile: /etc/ssl/certs/ca-certificates.crt
  • CApath: none
  • SSL re-using session ID
  • SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
  • ALPN, server did not agree to a protocol
  • Server certificate:
  • subject: C=xx; ST=xxxxxxxx; L=xxxxxxx; OU=xxxxx; O=xxxxxxxxxxxxx; CN=redacted.fqdn
  • start date: Nov 25 20:31:02 2020 GMT
  • expire date: Dec 27 20:31:02 2021 GMT
  • subjectAltName: host "redacted.fqdn" matched cert's "redacted.fqdn"
  • issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign RSA OV SSL CA 2018
  • SSL certificate verify ok.

POST /my.policy HTTP/1.1
Host: redacted.fqdn
User-Agent: User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
Accept: /
Cookie: LastMRH_Session=683093fe; MRHSession=57dbe7ab44e95f4076c2c13c683093fe
Content-Length: 73
Content-Type: application/x-www-form-urlencoded

  • upload completely sent off: 73 out of 73 bytes
  • Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    < Server: BigIP
    < Content-Type: text/html; charset=utf-8
    < Accept-Ranges: bytes
    < Connection: close
    < Date: Sun, 17 Jan 2021 09:36:56 GMT
    < Age: 32938
    < Content-Length: 26817
    < X-Frame-Options: DENY
    < Pragma: no-cache
    < Cache-Control: no-cache, must-revalidate
  • Replaced cookie LastMRH_Session="683093fe" for domain redacted.fqdn, path /, expire 0
    < Set-Cookie: LastMRH_Session=683093fe;path=/;secure
  • Replaced cookie MRHSession="861e06a324d3703a5690c814683093fe" for domain redacted.fqdn, path /, expire 0
    < Set-Cookie: MRHSession=861e06a324d3703a5690c814683093fe;path=/;secure
    <
  • Closing connection 2
    report_login_state
    error: Unexpected HTTP response code 200 received from https://redacted.fqdn/my.policy

--- end

What can we do from here? Just some reminders I am doing this on Arch Arm Linux armv7h.
Note that it is detecting the 3 fields username,password,token which is correct.

In examination of the above is not 200 completely valid? Why is it saying it is not?

I am not sure of the next sequence, should the code be changed to accept a 200?

What are your thoughts? or what should i try to do next?

I also note that if i put invalid details into the fields it is producing exactly the same results as above every time i try. So that implies perhaps the post is not correct?

Also, the epi (endpoint inspection) is skip-able in the subsequent page, i'll upload a screen shot for you. f5epi is available on AUR, but, i think we can bypass this.

This is the initial login page details
Screenshot at 2021-01-17 21-38-32

This is page after authentication, within browser.
awaiting connection

Thanks for the detailed response. So far it looks very similar. Two things to check:

  1. Whether the content of the 200 response matches that which you receive in the browser. If 200 is a valid response here, then we need to do some parsing of the content to be able to distinguish between credentials accepted and credentials rejected. Try adding debug ("%.*s\n", (int) session->http_response_body->len, session->http_response_body->str); before the check for 302 in on_login_result.

  2. (the tricky part) figuring out what Endpoint Inspector Application does and duplicating it. A starting point would be to check in your browser's development tools, it should be trying to launch it with some special scheme such as f5-endpoint-inspector://magical-cookies. The inspector will be taking those magical cookies and probably making a request to your backend with some other magical content. To see the contents of this request you could start with Wireshark/tcpdump but probably you will need to set up a HTTPS proxy (i.e. MITM yourself). You could try mitmproxy or Charles Proxy or similar for this. Once you have the content of the request, we need to figure out how to generate it based on the magical cookies. If we're lucky, it's a dumb simple response like allowed=true, if we're unlucky it will cryptographically generate something that will be validated by the backend - in that case you'd be getting into disassembling f5epi to see exactly how it does it.

I have implemented the code and have 2 x sets of output for

  1. a) failed login b) successful login
  2. I think some of the EPI detail starts in the 1.b)

Because the output is somewhat lengthy and contains sensitive info what is the best way to get that to you?

My email address is in the git commit log. You could attach a tarball or use wetransfer or similar.

Resolved with aae9c6c and 43fca01