Giter VIP home page Giter VIP logo

ucsf-vpn's Introduction

shellcheck codespell

For recent updates, see NEWS.

A UCSF VPN Client for Linux

The ucsf-vpn CLI command is a Linux-only tool for connecting to and disconnecting from the UCSF VPN server. It is based on the official UCSF instructions provided by the UCSF IT with additional instructions obtained through private communication.

Connect to the VPN

To connect to the UCSF VPN, call:

$ ucsf-vpn start --user=alice --token=prompt
WARNING: This action ('ucsf-vpn start') requires administrative ("sudo") rights.
Enter the password for your account ('alice84') on your local computer ('alice-laptop'):
Enter your UCSF Active Directory password: <password>
Enter 'push' (default), 'phone', 'sms', a 6 or 7 digit Duo token, or press your YubiKey: <six-digit token>
OK: OpenConnect status: 'openconnect' process running (started 00h00m01s ago on 2024-06-25T09:05:20-07:00; PID=14549)
OK: IP routing tunnels: [n=1] tun0
OK: Public IP information (UCSF IT): public_ip=10.49.88.54, network='UCSF Network - Private Space'
OK: Flavor: default
OK: Connected to the VPN

If you have problems connecting to the VPN using ucsf-vpn, make sure you use the correct username and password by logging in via the UCSF VPN web proxy.

Alternatively to command-line options, the username and password can also be specified in file ~/.netrc (or the file that environment variable NETRC specifies). See ucsf-vpn --help for more details. With a properly setup ~/.netrc entry, you can connect to the UCSF VPN using:

$ ucsf-vpn start
NOTE: Open the Duo Mobile app on your smartphone or tablet to confirm ...

after approving the push notification on your Duo Mobile app (the default is --token=push).

Disconnect from the VPN

To disconnect from the UCSF VPN, call:

$ ucsf-vpn stop
OK: OpenConnect status: No 'openconnect' process running
OK: IP routing tunnels: none
OK: Public IP information (UCSF IT): public_ip=123.145.254.42, network='not UCSF'
OK: Not connected to the VPN

Check status on VPN connection

To check whether you are connected to the UCSF VPN or not, call:

$ ucsf-vpn status
OpenConnect status: 'openconnect' process running (started 08h31m27s ago on 2024-06-25T16:20:00-07:00; PID=17419)
IP routing tunnels: [n=1] tun0
OK: Public IP information (UCSF IT): public_ip=10.49.88.54, network='UCSF Network - Private Space'
Flavor: default
Connected to the VPN

To get full details of your current internet connection in JSON format, call:

$ ucsf-vpn details
{
  "ip": "10.49.88.54",
  "city": "San Francisco",
  "region": "California",
  "country": "US",
  "loc": "37.7749,-122.4194",
  "org": "AS5653 University of California San Francisco",
  "postal": "94103",
  "timezone": "America/Los_Angeles",
  "readme": "https://ipinfo.io/missingauth"
}

Installation

The ucsf-vpn script is distributed under GPL (>= 2.1) and the source code is available at https://github.com/HenrikBengtsson/ucsf-vpn/. To "install" it, just do

$ curl -O https://raw.githubusercontent.com/HenrikBengtsson/ucsf-vpn/master/bin/ucsf-vpn
$ chmod ugo+x ucsf-vpn

Full command-line help

Connect to and Disconnect from the UCSF VPN

Usage:
 ucsf-vpn <command> [flags] [options]

Commands:
 start            Connect to VPN
 stop             Disconnect from VPN
 reconnect        Reconnect to VPN
 restart          Disconnect and reconnect to VPN
 toggle           Connect to or disconnect from VPN
 status           Display VPN connection status
 details          Display connection details in JSON format
 routing          Display IP routing details
 log              Display log file

Options:
 --token=<token>  One-time two-factor authentication (2FA) token or method:
                   - 'prompt' (user is prompted to enter the token),
                   - 'push' ("approve and confirm" in Duo app; default),
                   - 'phone' (receive phone call and "press any key"),
                   - 'sms' (receive code via text message),
                   -  6 or 7 digit token (from Duo app), or
                   -  44-letter YubiKey token ("press YubiKey")
 --user=<user>    UCSF Active Directory ID (username)
 --pwd=<pwd>      UCSF Active Directory ID password
 --presudo=<lgl>  Established sudo upfront (true; default) or not (false)

 --server=<host>  VPN server (default is 'remote.ucsf.edu')
 --realm=<realm>  VPN realm (default is 'Dual-Factor Pulse Clients')
 --url=<url>      VPN URL (default is https://{{server}}/pulse)
 --protocol=<ptl> VPN protocol, e.g. 'nc' (default) and 'pulse'
 --validate=<how> One or more of 'ipinfo', 'iproute', 'pid', 'ucsfit',
                  e.g. 'pid,iproute,ucsfit' (default)
 --theme=<theme>  Either 'cli' (default) or 'none'
 --flavor=<flvr>  Use a customized flavor of the VPN (default: 'none')

Flags:
 --verbose        More verbose output
 --help           Display full help
 --version        Display version
 --full           Display more information
 --force          Force command
 --args           Pass any remaining options to 'openconnect'

Examples:
 ucsf-vpn --version --full
 ucsf-vpn start --user=alice --token=push
 ucsf-vpn stop
 UCSF_VPN_TOKEN=prompt ucsf-vpn start --user=alice --pwd=secrets
 ucsf-vpn start
 ucsf-vpn routings --full


Environment variables:
 UCSF_VPN_PROTOCOL     Default value for --protocol
 UCSF_VPN_SERVER       Default value for --server
 UCSF_VPN_TOKEN        Default value for --token
 UCSF_VPN_THEME        Default value for --theme
 UCSF_VPN_VALIDATE     Default value for --validate
 UCSF_VPN_PING_SERVER  Ping server to validate internet (default: 9.9.9.9)
 UCSF_VPN_PING_TIMEOUT Ping timeout (default: 1.0 seconds)
 UCSF_VPN_EXTRAS       Additional arguments passed to OpenConnect

User credentials:
If user credentials (--user and --pwd) are neither specified nor given
in ~/.netrc, then you will be prompted to enter them. To specify them
in ~/.netrc file, use the following format:

  machine remote.ucsf.edu
      login alice
      password secrets

For security, the ~/.netrc file should be readable only by
the user / owner of the file. If not, then 'ucsf-vpn start' will
set its permission accordingly (by calling chmod go-rwx ~/.netrc).

Requirements:
* OpenConnect (>= 7.08) (installed: 8.20-1)
* sudo

VPN Protocol:
Different versions of OpenConnect support different VPN protocols.
Using '--protocol=nc' (default) has been confirmed to work when using
OpenConnect 7.08, and '--protocol=pulse' for OpenConnect 8.10.
The 'nc' protocol specifies the old "Juniper Network Connect" protocol,
and 'pulse' the newer "Pulse Secure" protocol.  For older version of
OpenConnect that recognizes neither, specify '--protocol=juniper',
which will results in using 'openconnect' legacy option '--juniper'.

Troubleshooting:
* Verify your username and password at https://remote.ucsf.edu/.
  This should be your UCSF Active Directory ID (username); neither
  MyAccess SFID (e.g. 'sf*****') nor UCSF email address will work.

Useful resources:
* UCSF VPN - Remote connection:
  - https://it.ucsf.edu/service/vpn-remote-connection
* UCSF Web-based VPN Interface:
  - https://remote-vpn01.ucsf.edu/ (preferred)
  - https://remote.ucsf.edu/
* UCSF Two-Factory Authentication (2FA):
  - https://it.ucsf.edu/services/duo-two-factor-authentication
* UCSF Managing Your Passwords:
  - https://it.ucsf.edu/services/managing-your-passwords

Version: 6.1.0
Copyright: Henrik Bengtsson (2016-2024)
License: GPL (>= 2.1) [https://www.gnu.org/licenses/gpl.html]
Source: https://github.com/HenrikBengtsson/ucsf-vpn

Required software

The uscf-vpn tool requires:

  1. OpenConnect (>= 7.08)
  2. Curl
  3. Bash
  4. Admin rights (sudo)

OpenConnect (>= 7.08) is available on for instance Ubuntu 18.04 LTS (Bionic Beaver), but not on older LTS version. For instance, Ubuntu 16.04 (Xenial Xerus) only provides OpenConnect 7.06, which fails to connect with an error. There is a confirmed way to force install this on to Ubuntu 16.04 from the Ubuntu 17.04 (Zesty) distribution, but it is not clear whether such an installation leaves the system in a stable state or not. Moreover, due to library dependencies, it appears not possible to have OpenConnect 7.08 and Pulse Secure 5.3-3 installed at the same time.

Privacy

The ucsf-vpn software pings 9.9.9.9 (https://www.quad9.net/; a nonprofit organization) to check whether there is a working internet connection or not. Environment variable UCSF_VPN_PING_SERVER can be use to specify a different ping server, e.g. UCSF_VPN_PING_SERVER=www.ucsf.edu.

The ucsf-vpn software also queries the https://ipinfo.io/ service to infer whether a VPN connection is established or not, and to provide public IP information on your current internet connection. To disable this check, use --validate=pid, or environment variable UCSF_VPN_VALIDATE=pid, which uses the PID file of OpenConnect to decide whether a VPN connection is established or not.

The ucsf-vpn software neither collects nor stores your local or UCSF credentials.

Building from source

The self-contained bin/ucsf-vpn script is generated from src/ucsf-vpn.sh and src/incl/*.sh. To rebuild bin/ucsf-vpn, use:

$ make build
./build.sh
Building bin/ucsf-vpn from src/ucsf-vpn ...
-r-xr-xr-x 1 alice alice 58584 Jun 26 09:43 bin/ucsf-vpn
Version built: 6.1.0
Building bin/ucsf-vpn from src/ucsf-vpn ... done

ucsf-vpn's People

Contributors

dimitripapadopoulos avatar henrikbengtsson avatar rossboylan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

ucsf-vpn's Issues

Generalize the command syntax

Currently specifying options as --foo=stuff does not work; it must be --foo stuff. It would be nice if the script could deal with arguments in a more standard way.

Failing that, perhaps a more explicit warning in the documentation or while parsing the arguments, might help.

For example, I call ucsf-vpn with the argument --token=6082911. That was passed on to openconnect, producing an error:

[DEBUG] call: sudo openconnect --script=/home/ross/src/ucsf-vpn/bin/selectiveTunnel --token=6082911 --juniper https://remote.ucsf.edu/pulse --background --user=rdboylan --passwd-on-stdin --quiet --authgroup="Dual-Factor Pulse Clients"
openconnect: option '--token=6082911' is ambiguous; possibilities: '--token-mode' '--token-secret'

Also, this seems to suggest the random unknown command arguments are passed to openconnect unchanged. Is that true? Is it desirable?

Replacing the = sign with a space worked properly.

UX: Add message what's next when using `push`, `phone` or `sms`

Clarify what's next when using push, phone or sms, e.g.

$ ucsf vpn start --token=push 
...
A push request has been sent to your Duo app. Please confirm there ...
$ ucsf vpn start --token=phone 
...
You will next receive a phone call to confirm that you want to connect to the VPN ...

Related to: Issue #30

Ubuntu 18.04: Issues with OpenConnect

Moving what @graft wrote in #4 (comment) to a new issue:

An issue I have been having lately with openconnect on some of my machines is a strange name service bug - the connection looks fine, an IP is assigned, but there is no ping available (or any other IP traffic apparently). This only happens on systems that use systemd-resolved - other systems I have that still use dnsmasq seem to work okay. I haven't really been able to understand what's going on here, but there is some discussion of the issue and a workaround here: dlenski/openconnect#104

The workaround, in case you encounter this issue on a new install (I'm running 18.04 ubuntu) is, after your connection is active, look for the following process:

run-parts --arg=-a --arg=tun0 /etc/resolvconf/update.d

Killing this will give you a working VPN connection.

WISH: Pre-specify multiple tokens with first being the default (if ENTER is pressed)

If CLI option --token or env var UCSF_VPN_TOKEN is not specified, or set to prompt, then we get:

$ ucsf vpn start
Enter 'push', 'phone', 'sms', a 6 or 7 digit token, or press your YubiKey: _

Feature Requests

It would be handy if pressing ENTER would default to the first, e.g.

$ ucsf vpn start
Enter 'push' (default), 'phone', 'sms', a 6 or 7 digit token, or press your YubiKey: <Press ENTER>

becomes

$ ucsf vpn start
Enter 'push' (default), 'phone', 'sms', a 6 or 7 digit token, or press your YubiKey: <push>
NOTE: Open the Duo Mobile app on your smartphone or tablet to confirm ...

Also, when prespecifying the token, it would be neat to be able to specify more than one, e.g.

$ export UCSF_VPN_TOKEN="push,digits,yubikey"
$ ucsf vpn start
Enter 'push' (default), a 6 or 7 digit token, or press your YubiKey: 

or

$ export UCSF_VPN_TOKEN="phone,push"
$ ucsf vpn start
Enter 'phone' (default), or 'push': 

--protocol=pulse fails fast; nc fails pretty fast

Generally, I've been unable to get a connection that stays open for > 15 minutes for quite awhile. Thinking this might be cured by shifting to newer protocols, I used pulse instead of the default nc as my --protocol. Leading to the main topic of this report

protocol=pulse can't negotiate connection

I've tried a couple of times with --debug --verbose. Because of possible security issues, I'm reluctant to post the full transcript. But the key part comes after Duo authentication and connection via HTTPS

Got HTTP response: HTTP/1.1 101 Switching Protocols
Unexpected IF-T/TLS packet when expecting configuration.
DEBUG: Removing file: /root/.config/ucsf-vpn/tmp.OFTlycxlLG-ipinfo.json
DEBUG: OpenConnect standard error:                                                                                                   
DEBUG: Enter user credentials:                                                                                                       
Enter secondary credentials:                                                                                                         
Secondary password:                                                                                                                  
Invalid ESP setup                                                                                                                    
Insufficient configuration found                                                                                                     
Creating SSL connection failed                                                                                                       
DEBUG: PID file does not exists: /root/.config/ucsf-vpn/openconnect.pid                                                              
DEBUG: pid=-1 

At the end there are no tunnels or routing changes.

Environment

ucsf-vpn 5.5.1: the .1 is for local modifications to use the .netrc for my regular user and switch the default to
protocol=${UCSF_VPN_PROTOCOL:-pulse}
Debian GNU/Linux 11/stable/bullseye, amd64 architecture (with some i386 installed)
openconnect 8.10-2+b1
DSL connection
going through deco router
running from a shell session that already sudo'd to root.

This is a more vanilla setting than my previous reports, in which I overrode the default script* for network routing setup so that only traffic for UCSF went through the tunnel. Also unlike my previous reports there is no nameserver running on the machine, though it does have resolvconf installed. One consequence is that the list of nameservers that end up in /run/resolvconf/resolv.conf always includes one entry from before the tunnel went up.

The software is generally newer than in my previous reports; in particular, openconnect is now at 8.10.

*This is the --script argument to openconnect; it defaults to /usr/share/vpnc-scripts/vpnc-script on Debian.

History

My main disk died about 6 weeks ago, and the problems appeared, or at least intensified, after I got back up. As partly noted above, they key things that changed were

  1. Debian 11 instead of Debian 10. Newer software, esp openconnect.
  2. Most routing and name service provided by a Deco router, which in turn uses my ISP for DNS. Previously my machine connected directly to the ISP, ran a DNS domain, did firewalling, DHCP ....
  3. ?Changes on the UCSF side.
  4. Custom script to setup routes disabled.
  5. Newer versions of ucsf-vpn. For most of the time I was using 5.4.

2 and 4 are simplifications; I will likely move back to my previous setup with time and/or recovery of the configuration files.

Theories

  1. This may well be an openconnect bug I referenced in another report:
    The Changelog has some interesting items. For the post 8.10 code it has
Fix a subtle bug which has prevented ESP rekey and ESP-to-TLS fallback from working reliably with the Juniper/oNCP protocol since v8.04. (#322, !293).
  1. Maybe Debian has blocked TLS 1.2, which the exchange uses, as insecure? But as far as I know, only 1.0 and 1.1 are insecure and blocked.
  2. I keep suspecting the reference to my ISP's nameserver is screwing things up, since any ucsf domains that resolve through it will get the external IP's. It is easy to imagine that breaking the connection. However, the documentation says the nameservers are tried in order, and the one from my ISP is 3rd on the list. So it seems unlikely it would ever be used. And I have tried manually editing it out of resolv.conf, and it hasn't helped that I can tell.

Alternatives

Without modification the program uses protocol=nc. I am able to connect with that; I'm just not able to stay connected for long: often only a few minutes, and usually not more than 15. That's why I tried protocol=pulse.

Secure Connector

Thanks to my manual invocation of openconnect I got to see the warning about Secure Connector shown at the bottom.

  • I'm somewhat surprised the message, with CLICK PROCEED, did not mess up the login via ucsf-vpn. When running openconnect directly I did not have to hit enter at that point.
  • The addition of secure connector, at least when enforced, seems likely to make access from linux challenging.
ross@secure-stretch:~/src/ucsf-vpn$ sudo openconnect  --juniper https://remote.ucsf.edu/pulse --user=rdboylan --authgroup="Dual-Factor Pulse Clients"
[sudo] password for ross: 
WARNING: Juniper Network Connect support is experimental.
It will probably be superseded by Junos Pulse support.
GET https://remote.ucsf.edu/pulse
Connected to 128.218.97.10:443
SSL negotiation with remote.ucsf.edu
Connected to HTTPS on remote.ucsf.edu
Got HTTP response: HTTP/1.1 302 Found
GET https://remote.ucsf.edu/dana-na/auth/url_3/welcome.cgi
SSL negotiation with remote.ucsf.edu
Connected to HTTPS on remote.ucsf.edu
 
UCSF Network Access Control
 
Starting 11/29/2018, you may receive a notification in your web browser asking you to download and install a Secure Connector agent when connecting to VPN.

This is a legitimate UCSF-mandated application.  Please follow the instructions.
 
Failure to do so could result in restricted network access at some point in the future.


UCSF IT Service Desk
MAIN: 415-514-4100
APeX: 415-514-APEX
http://help.ucsf.edu/
Fast, Efficient Solutions


CLICK PROCEED TO CONTINUE LOGGING IN

POST https://remote.ucsf.edu/dana-na/auth/url_3/welcome.cgi
.... [much more]

Error: Connection UCSF already exists

If there's already a UCSF connection setup in Pulse, we'll get an error 'Connection UCSF already exists' unless it's already pointing to https://remote.ucsf.edu/pulse. The same error occurs when attempting to use a different URL, e.g. ucsf vpn start --gui --url https://remote.ucsf.edu/openconnect.

WISH: Support for specifying multiple token alternatives

(This used to be part of #38)

We currently have in ucsf-vpn (>= 5.3.0):

$ ucsf vpn start
Enter 'push' (default), 'phone', 'sms', a 6 or 7 digit token, or press your YubiKey: ...

Feature Request

Also, when prespecifying the token, it would be neat to be able to specify more than one, e.g.

$ export UCSF_VPN_TOKEN="push,digits,yubikey"
$ ucsf vpn start
Enter 'push' (default), a 6 or 7 digit token, or press your YubiKey: 

or

$ export UCSF_VPN_TOKEN="phone,push"
$ ucsf vpn start
Enter 'phone' (default), or 'push': 

ucsf-vpn does not prompt for the second password.

I am providing correct password. It will wait for few mins after the UCSF password and then errors out. Here is the complete stack.

ubuntu1:~/ucsf-vpn$ ./ucsf-vpn start --token=push --user=xxxx --verbose
INFO: Pinging '8.8.8.8' once
INFO: Verified that internet connection works
INFO: Getting public IP (from https://ipinfo.io/ip)
INFO: Pinging '8.8.8.8' once
INFO: Preparing to connect to VPN server 'remote.ucsf.edu'
WARNING: This action ('ucsf-vpn start') requires administrative ("sudo") rights.
Enter the password for your account ('xxxxxxxx') on your local computer ('ubuntu1'):
INFO: Administrative ("sudo") rights establish
Enter your UCSF Active Directory password:
INFO: Connecting to VPN server 'remote.ucsf.edu'
WARNING: Juniper Network Connect support is experimental.
It will probably be superseded by Junos Pulse support
Failed to connect to host remote.ucsf.edu
Failed to open HTTPS connection to remote.ucsf.edu
Failed to obtain WebVPN cookie
ERROR: Failed to connect to VPN server (no running OpenConnect process). Check your username, password, and token.

Please help

Thanks
Anil

UCSF VPN works with OpenConnect (>= 7.08) [WARNING!!!]

WARNING WARNING WARNING: If you attempt the below OpenConnect 7.08 hack on Ubuntu 16.04, you might end up with a broken system. Proceed on your own risk.

Background

In mid-August 2017, OpenConnect stopped working with the UCSF VPN servers (which had been updated). The observed error reported was:

$ sudo openconnect --no-cert-check --user="$MYID" --authgroup="Single-Factor Pulse Clients" --juniper 'https://remote.ucsf.edu/pulse'
WARNING: Juniper Network Connect support is experimental.
It will probably be superseded by Junos Pulse support.
[...]
Connected to HTTPS on remote.ucsf.edu
Got HTTP response: HTTP/1.1 400 Bad Request
Unexpected 400 result from server
Creating SSL connection failed

Troubleshooting / Solution

On 2017-10-09, @graft found that this is a bug in OpenConnect (< 7.08) and that it has been fixed on OpenConnect 7.08. He reports that he can successful connect using:

$ sudo openconnect --servercert=sha256:82a0...<not sure if safe to share>...a304bb --authgroup="Single-Factor Pulse Clients" --juniper https://remote.ucsf.edu/openconnect

on Ubuntu 16.04 (Xenial). To install OpenConnect 7.08 he had to do some tricks (see comments below).

UX: Test sudo first

This can be achieved by sudo -v -n (== sudo --validate --non-interactive);

$ sudo -v -n 
sudo: a password is required

$ sudo -v -n 2> /dev/null
$ echo $?
1

$ sudo -v
[sudo] password for hb: 

$ sudo -v -n 2> /dev/null
$ echo $?
0

ROBUSTNESS: More precise killing of OpenConnect process

Make use of openconnect --pid-file=... option to record the PID of the process. This PID can then be used to kill the VPN process later, instead of as now, just killing all openconnect processed (pkill -INT openconnect)

      --pid-file=PIDFILE          Write the daemon's PID to this file

ERROR: Failed to infer public IP information

When I try to run ucsf-vpn start, I get a message ERROR: Failed to infer public IP information and the program quits. This also breaks my internet, and I need to run sudo pkill -9 openconnect to access the internet again.

This happens immediately after I successfully authenticate the Duo push notification on my phone for 2 factor authentication.

Here is a log of the output when I run the program:

jack@jaheira:~/src/ucsf-vpn/bin (git)-[master]- % sudo ./ucsf-vpn start --verbose
Enter username: <username>
Enter password: <password>
WARNING: Juniper Network Connect support is experimental.
It will probably be superseded by Junos Pulse support.
GET https://remote.ucsf.edu/pulse
Connected to 128.218.97.10:443
SSL negotiation with remote.ucsf.edu
Connected to HTTPS on remote.ucsf.edu
Got HTTP response: HTTP/1.1 302 Found
GET https://remote.ucsf.edu/dana-na/auth/url_3/welcome.cgi
SSL negotiation with remote.ucsf.edu
Connected to HTTPS on remote.ucsf.edu
                          @@@@@@@@@@@@@@@@@@@
                          !!!! ATTENTION !!!!
                          @@@@@@@@@@@@@@@@@@@

On September 10, 2019 UCSF IT will disable split-tunneling for Pulse Secure VPN clients.

For more information about VPN and this change see https://it.ucsf.edu/services/vpn.


CLICK PROCEED TO CONTINUE LOGGING IN

UCSF IT Service Desk
MAIN: 415-514-4100
APeX: 415-514-APEX
http://help.ucsf.edu/
Fast, Efficient Solutions

POST https://remote.ucsf.edu/dana-na/auth/url_3/welcome.cgi
Got HTTP response: HTTP/1.1 302 Moved
GET https://remote.ucsf.edu/dana-na/auth/url_3/welcome.cgi?
frmLogin
frmLogin
POST https://remote.ucsf.edu/dana-na/auth/url_3/login.cgi
Got HTTP response: HTTP/1.1 302 Moved
GET https://remote.ucsf.edu/dana-na/auth/url_3/welcome.cgi?p=more-cred&id=state_5289aea5ba627fb1ec589dda264e438d
frmLogin
password#2:
POST https://remote.ucsf.edu/dana-na/auth/url_3/login.cgi
Got HTTP response: HTTP/1.1 302 Moved
GET https://remote.ucsf.edu/dana-na/auth/url_3/welcome.cgi?p=user-confirm&id=state_5289aea5ba627fb1ec589dda264e438d
POST https://remote.ucsf.edu/dana-na/auth/url_3/login.cgi
Got HTTP response: HTTP/1.1 302 Moved
GET https://remote.ucsf.edu/dana/home/starter0.cgi?check=yes
Connected as 10.48.50.173, using SSL, with ESP in progress
Continuing in background; pid 32511
RTNETLINK answers: File exists
ERROR: Failed to infer public IP information
ERROR: Failed to infer public IP information
RESULT: Connected to the UCSF network [ ()]

False error on 'ucsf vpn start' failing

Issue

The following error is a bit confusing, because it's actually not true. The VPN connection was indeed correctly establish:

$ ucsf vpn start
WARNING: This action ('ucsf vpn start') requires administrative ("sudo") rights.
Enter the password for your account ('alice') on your local computer ('my-laptop'): 
Enter 'push' (default), 'phone', 'sms', a 6 or 7 digit token, or press your YubiKey: <push>
NOTE: Open the Duo Mobile app on your smartphone or tablet to confirm ...
OK: OpenConnect status: 'openconnect' process running (PID=2209405)
ERROR: Public IP information: ip=123.145.254.42, hostname=123.145.254.42.fiber.dynamic.sonic.net, org=AS46375 Sonic Telecom LLC

However, we're connected to the VPN, which can be seen if we call the following immediately after:

$ ucsf vpn status
OpenConnect status: 'openconnect' process running (PID=2209405)
Public IP information: ip=128.218.43.42, hostname=, org=AS5653 University of California San Francisco
Connected to the VPN

Task

I'm not sure what causes this, but it could be that it takes a while before the public IP information is updated, so we either have to wait longer, or try multiple times before giving that error.

username:fgets (stdin): Resource temporarily unavailable

When I try to use the 4.0 master release with OpenConnect 7.08 on Debian stretch it failed to connect; the error seems to be the one in the subject line. I speculate that openconnect is having trouble reading the user name from ucsf-vpn.

Actually, I just got it to work with a different key, after finding the one I used was already used up. I don't know if my attempts used it up, or if that was earlier. So this report may just indicate that better error reporting for failed logins would be helpful, i.e., a message that the key was rejected.

I still have the pulse client in /usr/local/, although it disappeared from my menu before I took in the latest updates. I mention this because your notes indicate that there is a conflict between openconnect and pulse, which I suppose could be in play.

I am running in a VirtualBox vm with bridged networking.

I am running the program in place in the git working directory and have a .netrc file with the name and password. It does have some local changes so that I can enter 7 digit Duo keys (which is what I have). I'll put those in a pull request.

BTW, I never got the program working completely with the pulse client; there seemed to be some issue communicating with the pulse GUI after it was launched.

I originally ran this from a shell inside emacs. Thinking that was the problem, I ran in a regular terminal. It failed in the same way.

Final comment: the username request seems to appear after the initial login and after the 2nd factor has been delivered, which seems quite late in the process.

Here's the log on the terminal with debugging:

ross@secure-stretch:~/src/ucsf-vpn$ date ; bin/ucsf-vpn start --token prompt --verbose --debug
Tue Aug 14 13:20:25 PDT 2018
[DEBUG] Method: openconnect
[DEBUG] Will prompt user for 2FA token
[DEBUG] call: bin/ucsf-vpn start --token prompt --verbose --debug
[DEBUG] action: start
[DEBUG] VPN server: remote.ucsf.edu
[DEBUG] Realm: 'Dual-Factor Pulse Clients'
[DEBUG] user: 
[DEBUG] pwd=<missing>
[DEBUG] token=<prompt>
[DEBUG] verbose: TRUE
[DEBUG] force: FALSE
[DEBUG] skip: FALSE
[DEBUG] dryrun: FALSE
[DEBUG] extras: 
[DEBUG] method: openconnect
[DEBUG] gui: TRUE
[DEBUG] speed: 1.0
[DEBUG] is_online()
[DEBUG] online: TRUE
[DEBUG] public_ip()
[DEBUG] connection_details()
[DEBUG] Querying https://ipinfo.io/ip for public IP:
[DEBUG] Public connection information: {
  "ip": "66.181.128.6",
  "hostname": "m128-6.dsl.rawbw.com",
  "city": "San Francisco",
  "region": "California",
  "country": "US",
  "loc": "37.7484,-122.4160",
  "postal": "94110",
  "org": "AS7961 Raw Bandwidth Communications, Inc."
}
[DEBUG] is_connected(66.181.128.6)
[DEBUG] connection_details()
[DEBUG] Querying https://ipinfo.io/ip for public IP:
[DEBUG] Public connection information: {
  "ip": "66.181.128.6",
  "hostname": "m128-6.dsl.rawbw.com",
  "city": "San Francisco",
  "region": "California",
  "country": "US",
  "loc": "37.7484,-122.4160",
  "postal": "94110",
  "org": "AS7961 Raw Bandwidth Communications, Inc."
}
[DEBUG] Detected .netrc file: /home/ross/.netrc
[DEBUG] - search: remote.ucsf.edu
[DEBUG] - search pattern: ^[ \t]*machine[ \t]+remote.ucsf.edu([ \t]+|$)
[DEBUG] - found: remote.ucsf.edu
[DEBUG] - user=rdboylan
[DEBUG] - pwd=<hidden>
[DEBUG] PROMPT: Asking user to enter one-time token:
Enter 'push', 'phone', 'sms', a 6 or 7 digit Duo token, or press your YubiKey: [DEBUG] Duo token detected
<valid token>
[DEBUG] - token=<hidden>
[DEBUG] call: bin/ucsf-vpn start --token prompt --verbose --debug
[DEBUG] user: rdboylan
[DEBUG] pwd: <hidden>
[DEBUG] token: <hidden>
[DEBUG] opts:  --juniper https://remote.ucsf.edu/pulse --background --user=rdboylan --passwd-on-stdin
[DEBUG] call: sudo openconnect  --juniper https://remote.ucsf.edu/pulse --background --user=rdboylan --passwd-on-stdin --authgroup="Dual-Factor Pulse Clients"
[sudo] password for ross: 
WARNING: Juniper Network Connect support is experimental.
It will probably be superseded by Junos Pulse support.
GET https://remote.ucsf.edu/pulse
Connected to 128.218.97.10:443
SSL negotiation with remote.ucsf.edu
Connected to HTTPS on remote.ucsf.edu
Got HTTP response: HTTP/1.1 302 Found
GET https://remote.ucsf.edu/dana-na/auth/url_3/welcome.cgi
SSL negotiation with remote.ucsf.edu
Connected to HTTPS on remote.ucsf.edu
frmLogin
frmLogin
POST https://remote.ucsf.edu/dana-na/auth/url_3/login.cgi
SSL negotiation with remote.ucsf.edu
Connected to HTTPS on remote.ucsf.edu
Got HTTP response: HTTP/1.1 302 Moved
GET https://remote.ucsf.edu/dana-na/auth/url_3/welcome.cgi?p=more-cred&id=state_17ec986cd0ead339f4dda809effd0845
SSL negotiation with remote.ucsf.edu
Connected to HTTPS on remote.ucsf.edu
frmLogin
password#2:
POST https://remote.ucsf.edu/dana-na/auth/url_3/login.cgi
SSL negotiation with remote.ucsf.edu
Connected to HTTPS on remote.ucsf.edu
Got HTTP response: HTTP/1.1 302 Moved
GET https://remote.ucsf.edu/dana-na/auth/url_3/welcome.cgi?p=failed&auth=2
SSL negotiation with remote.ucsf.edu
Connected to HTTPS on remote.ucsf.edu
frmLogin
username:fgets (stdin): Resource temporarily unavailable

[DEBUG] is_online()
[DEBUG] public_ip()
[DEBUG] connection_details()
[DEBUG] Querying https://ipinfo.io/ip for public IP:
[DEBUG] Public connection information: {
  "ip": "66.181.128.6",
  "hostname": "m128-6.dsl.rawbw.com",
  "city": "San Francisco",
  "region": "California",
  "country": "US",
  "loc": "37.7484,-122.4160",
  "postal": "94110",
  "org": "AS7961 Raw Bandwidth Communications, Inc."
}
[DEBUG] is_connected(66.181.128.6)
[DEBUG] connection_details()
[DEBUG] Querying https://ipinfo.io/ip for public IP:
[DEBUG] Public connection information: {
  "ip": "66.181.128.6",
  "hostname": "m128-6.dsl.rawbw.com",
  "city": "San Francisco",
  "region": "California",
  "country": "US",
  "loc": "37.7484,-122.4160",
  "postal": "94110",
  "org": "AS7961 Raw Bandwidth Communications, Inc."
}
[DEBUG] status(FALSE 66.181.128.6)
[DEBUG] public_hostname()
[DEBUG] connection_details()
[DEBUG] Querying https://ipinfo.io/ip for public IP:
[DEBUG] Public connection information: {
  "ip": "66.181.128.6",
  "hostname": "m128-6.dsl.rawbw.com",
  "city": "San Francisco",
  "region": "California",
  "country": "US",
  "loc": "37.7484,-122.4160",
  "postal": "94110",
  "org": "AS7961 Raw Bandwidth Communications, Inc."
}
[DEBUG] public_ip()
[DEBUG] connection_details()
[DEBUG] Querying https://ipinfo.io/ip for public IP:
[DEBUG] Public connection information: {
  "ip": "66.181.128.6",
  "hostname": "m128-6.dsl.rawbw.com",
  "city": "San Francisco",
  "region": "California",
  "country": "US",
  "loc": "37.7484,-122.4160",
  "postal": "94110",
  "org": "AS7961 Raw Bandwidth Communications, Inc."
}
RESULT: Not connected to the UCSF network [m128-6.dsl.rawbw.com (66.181.128.6)]

Clearer indication of disconnect

This is essentially a cosmetic issue. When the connection times out, the only indication I see on the terminal where I invoked the program is

ross@barley:~/src/ucsf-vpn/bin$ date; ./ucsf-vpn start
# various messages
OK: Connected to the VPN
ross@barley:~/src/ucsf-vpn/bin$ DEBUG: running list-records in /etc/resolvconf/run/interface: enp5s0.inet
lo.named

And there is no prompt. It would be nice if it said "Disconnected" or something like that.

It's also a little odd I'm getting the DEBUG message, though that, and perhaps the 2 lines after it, may be coming from my selectiveTunnel script. The code is from the develop branch.

ERROR: No internet connection on stop

I get an odd error message when I end my session. I know VPN was active moments before because I had just used it, and I know my regular connection is active now because I'm using it.

As far as I can tell, the stop operation worked fine. So, seemingly, a cosmetic issue.

ross@secure-stretch:~/src/ucsf-vpn$ bin/ucsf-vpn stop
[sudo] password for ross: 
RESULT: Killed local ('openconnect') VPN process
ERROR: No internet connection
RESULT: 

DNS not configured for internal use, after connecting to the VPN?

Hello, thank you for this great tool!

I am using version 5.5.0 with openconnect 8.20-1, on PopOS 22.04. Sporadically, it seems like after I connect to the VPN, I do not have the internal DNS entries on my computer, and thus I can only access internal sites if I know their IP addresses. Have you seen this issue before, and if so, do you have any suggestions for how to address it?

Please let me know if I can supply any other debug information.

Thanks!

NOTIFICATION (2020-06-01): Certificate from VPN server "remote.ucsf.edu" failed verification. Reason: certificate expired

Issue

A cert that remote.ucsf.edu uses expired on 2020-05-30. This causes problems connecting to the UCSF VPN network. Using ucsf vpn start (OpenConnect) on an up-to-date Ubuntu 18.04.4 LTS system with OpenConnect 7.08-3ubuntu0.18.04.1 (ucsf vpn --help shows this) reports:

$ ucsf vpn start
Enter the password for your account ('slice') on your local computer ('notebook'): ********
Enter 'push', 'phone', 'sms', a 6 or 7 digit token, or press your YubiKey: <YubiKey token>
WARNING: Juniper Network Connect support is experimental.
It will probably be superseded by Junos Pulse support.

Certificate from VPN server "remote.ucsf.edu" failed verification.
Reason: certificate expired
To trust this server in future, perhaps add this to your command line:
    --servercert sha256:585099c60198e420c12c85218efbd334eb6edf9ebb831d509a04d47accaca684
Enter 'yes' to accept, 'no' to abort; anything else to view: X.509 Certificate Information:
	Version: 3
	Serial Number (hex): 0e48e4970496aa30ec86018e8e0fc062
	Issuer: CN=InCommon RSA Server CA,OU=InCommon,O=Internet2,L=Ann Arbor,ST=MI,C=US
	Validity:
		Not Before: Fri Oct 13 00:00:00 UTC 2017
		Not After: Mon Oct 12 23:59:59 UTC 2020
	Subject: CN=remote.ucsf.edu,OU=UCSF-General,O=University of California\, San Francisco,street=500 Parnassus Avenue,street=G-14,L=San Francisco,ST=CA,postalCode=94143-0225,C=US
	Subject Public Key Algorithm: RSA
	Algorithm Security Level: Medium (2048 bits)
		Modulus (bits 2048):
			00:ba:89:c7:cb:96:04:2b:6f:8a:13:ae:cc:c9:1a:4b
			ca:b1:02:10:1e:f8:b4:8d:ee:df:fb:21:61:30:e7:e1
			98:62:a2:ed:4a:08:c3:c4:4c:31:79:ba:22:dc:b0:b5
			78:97:f6:91:68:4b:42:9c:78:59:04:00:cb:62:09:f1
			a8:18:1a:64:4e:6d:4c:37:a7:f2:fa:b8:52:f0:95:85
			5d:35:19:9b:89:a9:fd:f4:75:a0:22:a2:62:30:43:b0
			fa:14:57:29:59:06:40:02:4a:b9:1a:1b:54:d8:c9:b0
			d2:ee:41:d2:a8:2a:c9:2f:80:66:16:2d:98:3d:2f:e3
			22:bb:2c:08:1a:3c:99:ce:25:7f:72:40:39:c5:45:61
			be:a3:16:2e:08:3d:eb:14:03:ea:3c:29:e2:f1:a4:8c
			80:b9:fe:14:57:8d:a2:f3:bd:ed:da:20:a2:31:43:ac
			b7:25:b7:ef:27:14:31:f5:04:d1:e2:65:99:86:f7:69
			92:61:db:8e:6f:a4:d3:e7:21:f3:82:16:63:ec:ad:2d
			b4:e8:a1:bf:2f:e7:ff:a6:89:0a:70:ee:9d:7f:53:5a
			bd:40:3c:5e:8b:de:e5:4f:44:d9:1e:96:75:f3:7a:e5
			61:0b:95:a2:fd:1f:af:81:32:2c:b0:fa:0b:73:5e:c9
			cb
		Exponent (bits 24):
			01:00:01
	Extensions:
		Authority Key Identifier (not critical):
			1e05a3778f6c96e25b874ba6b486ac71000ce738
		Subject Key Identifier (not critical):
			8a072474811e19074caa8215c430bafff70c2c9c
		Key Usage (critical):
			Digital signature.
			Key encipherment.
		Basic Constraints (critical):
			Certificate Authority (CA): FALSE
		Key Purpose (not critical):
			TLS WWW Server.
			TLS WWW Client.
		Certificate Policies (not critical):
			1.3.6.1.4.1.5923.1.4.3.1.1
				URI: https://www.incommon.org/cert/repository/cps_ssl.pdf
			2.23.140.1.2.2
		CRL Distribution points (not critical):
			URI: http://crl.incommon-rsa.org/InCommonRSAServerCA.crl
		Authority Information Access (not critical):
			Access Method: 1.3.6.1.5.5.7.48.2 (id-ad-caIssuers)
			Access Location URI: http://crt.usertrust.com/InCommonRSAServerCA_2.crt
			Access Method: 1.3.6.1.5.5.7.48.1 (id-ad-ocsp)
			Access Location URI: http://ocsp.usertrust.com
		Subject Alternative Name (not critical):
			DNSname: remote.ucsf.edu
			DNSname: 2252-00f1-vpn01.ucsf.edu
			DNSname: 3002-s251-vpn01.ucsf.edu
			DNSname: remote-vpn01.ucsf.edu
			DNSname: remote-vpn02.ucsf.edu
	Signature Algorithm: RSA-SHA256
	Signature:
		0f:7a:ce:40:b0:80:cc:de:c9:c7:c9:2b:31:c6:2c:69
		f2:af:7e:9b:30:20:3b:e2:9b:86:6a:1f:34:8f:15:84
		53:43:a3:45:e1:63:c7:b4:4c:65:e1:bb:ac:43:a0:c9
		1a:85:e1:87:18:0d:bc:b5:e3:ed:75:bd:d4:39:13:c0
		64:52:c7:6c:75:09:d4:0f:5e:5f:af:7e:03:d0:1f:3b
		f7:3e:b5:36:10:5b:b0:1f:66:2f:81:6e:63:46:78:70
		81:d1:11:ce:50:7d:66:16:41:3d:9e:4d:c6:d1:23:2f
		53:3e:54:4e:3a:2c:f6:11:90:72:ab:34:49:8b:6e:5f
		5b:39:12:46:99:30:8d:8b:fa:f0:0c:96:85:1b:05:f7
		6a:0e:92:3b:86:af:97:96:12:44:a6:49:e5:83:80:96
		3c:c9:61:10:3d:34:d1:65:0a:d1:f5:0e:73:57:e3:42
		5c:ae:f2:30:f2:e2:23:57:76:9e:4e:92:48:37:c0:72
		ba:b7:09:74:60:6a:dc:9c:f6:97:2a:fb:84:8d:b3:5d
		f1:d8:44:a8:e2:69:56:04:a7:24:60:5e:2e:36:6c:49
		e8:3a:1f:7e:92:8b:47:13:71:4d:40:e1:ad:80:09:6f
		ae:24:b9:8f:e0:e7:65:60:b0:2a:25:07:11:20:1c:28
Other Information:
	Fingerprint:
		sha1:8e72bea0f6642d30b620b808588bcc894f7e7012
		sha256:02aee3c9f04edfb3e6ca06e5bf1f754afa1062dd7847d0a791460ed26b8c8e5f
	Public Key ID:
		sha1:1eb545ab1428754f26a8ceac368a324ae0100167
		sha256:585099c60198e420c12c85218efbd334eb6edf9ebb831d509a04d47accaca684
	Public Key PIN:
		pin-sha256:WFCZxgGY5CDBLIUhjvvTNOtu3567gx1QmgTUesyspoQ=
	Public key's random art:
		+--[ RSA 2048]----+
		|+ E    ..o+ +    |
		| +    . o. B .   |
		|.      o  o +    |
		| .    .  o +     |
		|o    +  S o      |
		|+     +. .       |
		| o   .  .        |
		|+.  +            |
		|=..o .           |
		+-----------------+
Server key hash: sha256:585099c60198e420c12c85218efbd334eb6edf9ebb831d509a04d47accaca684

Certificate from VPN server "remote.ucsf.edu" failed verification.
Reason: certificate expired
To trust this server in future, perhaps add this to your command line:
    --servercert sha256:585099c60198e420c12c85218efbd334eb6edf9ebb831d509a04d47accaca684
Enter 'yes' to accept, 'no' to abort; anything else to view: fgets (stdin): Operation now in progress
ERROR: Failed to connect to VPN server (no running OpenConnect process). Check your username, password, and token.

$ 

Details

From https://www.ssllabs.com/ssltest/analyze.html?d=remote.ucsf.edu (takes 1-2 minutes), we get:

  • Subject: USERTrust RSA Certification Authority
  • Fingerprint SHA256: 1a5174980a294a528a110726d5855650266c48d9883bea692b67b6d726da98c5
  • Pin SHA256: x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4=
  • Valid until: Sat, 30 May 2020 10:48:38 UTC (expired 2 days, 8 hours ago) EXPIRED
  • Key: RSA 4096 bits (e 65537)
  • Issuer: AddTrust External CA Root
  • Signature algorithm: SHA384withRSA

Robust detection of whether connection to vpn succeeded

The immediate issue for me is that if I modify the networking scripts so that only UCSF internal IPs are forwarded through the tunnel, the current test will think I have not connected to the VPN even if I have. The test relies on accessing an internet site that is not inside of UCSF, and so the packets to it do not go through UCSF, and the return info indicates a non-UCSF location.

One possibility would be to ping an internal IP as an indicator of successful connection. Of course, that is subject to the vagaries of the routing rules on the internal network, whether UCSF decides to block pings, possible changes in the target system, etc.

Another issue is whether this alternate mechanism should be the only mechanism, a user selectable option, or something else.

There is a related request to UCSF about supporting some mechanism for determing if connection to the VPN succeeded.

ucsf vpn stop: try a bit more when failing

Issue

If I forget to disconnect from the VPN and sleep my notebook, then I have a broken internet connection when I open it up again. Then I do:

$ ucsf vpn stop
WARNING: This action ('ucsf vpn stop') requires administrative ("sudo") rights.
Enter the password for your account ('alice') on your local computer ('laptop'): 
ERROR: Failed to terminate VPN process ('openconnect' with PID 29161). You could manually kill
*all* OpenConnect processes by calling 'sudo pkill -INT openconnect'. CAREFUL! [ucsf-vpn 5.3.0-9001,
OpenConnect 7.08-3ubuntu0.18.04.2]
$ 

However, if I call it again, it always managed to reset the connection;

$ ucsf vpn stop
OK: OpenConnect status: No 'openconnect' process running
OK: Public IP information: ip=192.124.70.215, hostname=192-124-70-215.ips-provider.org, org=AS46313
ISP Provider
OK: Not connected to the VPN
$ 

Suggestion

Figure out why the first ucsf vpn stop fails but then the second works. Understanding that should make it possible to make the first ucsf vpn stop call to succeed.

Important Safety Tip - Turn off host VPN when using in a virtual machine.

I was having disconnection issues, the vpn would drop after about 30-40 seconds. I am using Ubuntu 20 Desktop (vm running on Fusion). The problem ended up being the host computer also had an active NordVPN connection. Turning off the host VPN connection completely fixed the issue. Rock solid at this point, very nice and easy to use.

Aslo confirming this is working (with open-vpn) on:

$ uname -a
Linux zatoichi 5.8.0-38-generic #43~20.04.1-Ubuntu SMP Tue Jan 12 16:39:47 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

pause and resume: is it possible?

Note to self: Instead of full on start and stop, which takes time, can one achieve a pause and resume?

$ man openconnect
...
SIGNALS
       In the data phase of the connection, the following signals are handled:

       SIGINT performs  a  clean shutdown by logging the session off, disconnecting from the gateway, and running
              the vpnc-script to restore the network configuration.

       SIGHUP disconnects from the gateway and runs the vpnc-script, but does  not  log  the  session  off;  this
              allows for reconnection later using --cookie.

       SIGUSR2
              forces an immediate disconnection and reconnection; this can be used to quickly recover from LAN IP
              address changes.

       SIGTERM
              exits immediately without logging off or running vpnc-script.

COVID-19: Use of alternative server (please don't)

UPDATE 2020-03-17: Please do *not use the alternative server for your VPN client. UCSF wants to reserve that one for the web-based VPN only (which cannot be loaded balanced).

FYI, the default UCSF VPN server is remote.ucsf.edu. I've just verified that our ucsf vpn tool supports also the newly added another server by specifying:

$ ucsf vpn start --server <other server>

Please note that this needs to be specified without an equal sign (=), cf. Issue #16.

I'll add it to the todo list to make it possible to set the default server via environment variable UCSF_VPN_SERVER (not yet implemented)

Selective tunneling

WHY

The standard way this tool, and AFAIK other UCSF VPN clients, work is that all traffic gets sent through the UCSF network. This seemed undesirable to me because

  1. It cut off my local network. I couldn't print, and other computers in my house couldn't use my machine, which, among other things was serving as the internet gateway and primary server.
  2. It meant that personal, non-work-related traffic would still flow through the UCSF network, exposing me to potential snooping as well as the charge of abusing the UCSF network for improper uses such as streaming a video for personal entertainment.
  3. The extra fuss of the VPN seemed likely to degrade connection quality, and increase CPU use, for things like video streaming.

On the other hand:

  1. Sending everything through the VPN, according to some messages, is now mandatory, at least on the Windows/Mac platforms where one has to take what UCSF gives. The justification was added security because it would prevent outside networks from getting in via the connections that didn't go through the VPN. This seems a little thin to me, since one can still get a virus when not connected and then have it spread once connected. (Yes, I know other security software is supposed to prevent that, but nothing is perfect.)
  2. My understanding that all traffic goes through the VPN may be wrong, at least now. That is, local networks like 192.168.x.y may not go through the VPN. Even if that's true, accessing email on my ISP's servers might be challenging if I had to go through the VPN.

HOW

The selective branch of https://github.com/RossBoylan/ucsf-vpn/ has the code I've been using for quite awhile to do selective tunneling. Most of the action is in the selectiveTunnel script, which is a modified version of the standard helper script that openConnect uses to manage networking. It works in connection with a file of the IP ranges that make up the internal network to which one is connecting. UCSF network services has requested that this not be made public, and so it is not on github.

ucsf-vpn needs two types of changes. It needs to call openconnect with the name of the revised helper script; for now that is hard-coded. Second, the selective tunneling violates some of the assumptions the script makes in identifying whether one is connected. It does this by executing

 curl --silent https://ipinfo.io/json

and seeing what comes back. But, since ipinfo.io is not inside the VPN, the traffic doesn't go through the VPN, and so the info that comes back indicates there is no VPN connection--even though there is.

When I discovered that curl had an --interface argument I thought I could use it to guarantee that the query went out through the VPN. But nothing ever comes back when I do that. I don't know why.

If you go a couple of commits back, to 7974b85, you'll see the code I was using that was working. That was based on a much older version of master, which used different strategies for figuring out the connection info. Those strategies also needed to be tweaked for the selective tunneling. The current code in master is more robust, but it still can't deal with the selective tunneling.

I should also note that the new code in selectiveTunnel works for me on Debian GNU/Linux 10. It will probably work on most linux's; it is unlikely it will work in other OS's.

QUESTIONS

Do you think selective tunneling is a desirable feature? A security risk?

How can we determine if we have a connection to the VPN when selective tunneling is in place?

STATUS

If you use the current tip of my selective branch it won't work [actually it will with either of the 2 approaches describe in later posts]. You'll get a selective connection, but ucsf-vpn won't realize that. Also, it won't work unless you have a list of IP ranges considered inside the vpn in /etc/vpnc/UCSFIntranet.

I'm going to continue using the older version mentioned above pending a better solution.

sudo warnings in logs

Since upgrading to the current (actually, development) code my logs are showing repeated notices from sudo that "a password is required" for me. The message indicates PWD is my ucsf-vpn directory.

It's true a password is required, but the old code wasn't producing log messages that were getting flagged.

There may not be anything particularly wrong with the current behavior. I noticed it because my automatic log-scanning software, logcheck, picks up these messages as "Security Events" indicating a moderate level of risk. I do not usually get reports with such severity.

I can just ignore the messages, or even add a pattern that will make logcheck ignore the messages.

Guess: the old code always prompted for a password, while the new code tries to sudo in hopes there will still be a password cached (I think the release notes mentioned this)? And if it isn't, it triggers the warning in the logs and the request to enter a password?

If there's a way to check if the password is cached without triggering the warning, that would be great. Quick search suggests (https://unix.stackexchange.com/questions/115506/sudo-testing-for-credentials) checking the return status of sudo -nv 2> /dev/null to tell if pasword-free sudo works, but I suspect that would trigger the same warning. A workaround might be to check for the cache file, which seems to be /var/run/sudo/ross for me but that's likely system dependent (/var/lib/sudo is mentioned elsewhere) and would still require figuring out if the validity interval had passed (unless it is reliably deleted when it is too old. I see a file from 28 minutes ago, and so I don't think it is deleted when it expires)

Maybe PAM provides some tools that would help. I'm not that familiar with it, but I assume it has a role in all this.

Even sudo -ls require credentials, and so I suspect it is hard to use sudo to test for credentials without triggering attempts to elevate. The -n option above, for non-interactive, suppresses the prompt, but that doesn't necessarily mean it suppresses the failure report.

openconnect --juniper obsolescence?

In brief, maybe use --protocol=nc or --protocol=pulse in place of --juniper for openconnect. --protocol=pulse probably requires a pretty current version of openconnect, since it is not listed from my 8.02 release.

To clarify: --juniper, though not a documented option for (my) openconnect, seems to be working fine. But it's probably not future-proof.

ucsf-vpn calls DEBUG: call: sudo openconnect --script=/home/ross/src/ucsf-vpn/bin/selectiveTunnel --reconnect-timeout=50 --juniper https://remote.ucsf.edu/pulse --background --user=xxx --passwd-on-stdin --pid-file=/root/.config/ucsf-vpn/openconnect.pid --authgroup="Dual-Factor Pulse Clients" for me (the --script and --reconnect-timeout arguments are from local customization).

I have openconnect 8.02-1+deb10u1 on Debian 10 aka buster aka oldstable. The man page does not list --juniper as an option, though it does have

--protocol=PROTO
Select VPN protocol PROTO to be used for the connection. Supported protocols are anyconnect for Cisco AnyConnect (the default), nc for experimental support for Juniper Network Connect (also supported by Junos Pulse servers), and gp for experimental support for PAN GlobalProtect.

Also, there's this warning on the terminal when I connect (usually without the DEBUG)

DEBUG: WARNING: Juniper Network Connect support is experimental.
It will probably be superseded by Junos Pulse support.

Since the man page quoted above continues to describe Juniper/Junos support as experimental, switching to --protocol=nc may not have any effect on the warning.

Upstream openconnect is currently at 8.10; Debian stable has 8.10 as well. The latest man page still refers to support for Juniper as experimental. It has, however, gained a --protocol=pulse option.

The Changelog has some interesting items. For the post 8.10 code it has

Fix a subtle bug which has prevented ESP rekey and ESP-to-TLS fallback from working reliably with the Juniper/oNCP protocol since v8.04. (#322, !293).

And 8.06 mentions

Explain experimental Pulse support for servers where Juniper oNCP is disabled (!48).

I have no idea what oNCP is, or if UCSF is using it. The reference (!48) on the previous changelog entry is illuminating; it says that oNCP was Juniper's old protocol, while pulse is the new one. The discussion notes pulse support was added experimentally to openconnect 8.04.

WISH: Scan pulsesvc.log for common errors

Add ucsf-vpn troubleshoot that scan $HOME/.pulse_secure/pulse/pulsesvc.log for common errors, e.g.

grep -F Error $HOME/.pulse_secure/pulse/pulsesvc.log
20170831160620.761400 pulsesvc[p2525.t2525] IpcConn.error bind failed to port 4242. Error 98 (ncipc.cpp:85)
20171115184045.222069 pulsesvc[p5494.t5494] IpcConn.error bind failed to port 4242. Error 98 (ncipc.cpp:85)
20171115184151.573381 pulsesvc[p5716.t5716] IpcConn.error bind failed to port 4242. Error 98 (ncipc.cpp:85)
20171115184207.866338 pulsesvc[p5803.t5803] IpcConn.error bind failed to port 4242. Error 98 (ncipc.cpp:85)
20171115184249.226738 pulsesvc[p6000.t6000] IpcConn.error bind failed to port 4242. Error 98 (ncipc.cpp:85)
20171115184302.611098 pulsesvc[p6054.t6054] IpcConn.error bind failed to port 4242. Error 98 (ncipc.cpp:85)

Annoying message: ERROR: Failed to infer public IP information

Using ucsf vpn start often (always?) results in a non-critical message "ERROR: Failed to infer public IP information", e.g.

$ ucsf vpn start
WARNING: Juniper Network Connect support is experimental.
It will probably be superseded by Junos Pulse support.
password#2:
ERROR: Failed to infer public IP information
RESULT: Connected to the UCSF network [ip=128.x.x.x, hostname='', org='AS5653 University of California San Francisco']

Since this happens so frequently it is of little use. This might be what is brought up in Issue #17.

Credentials in .netrc instead?

Instead of the home-made .ucsfvpnrc file format, whould it make sense/be valid to specify credential in a ~/.netrc file, e.g.

machine remote.ucsf.edu
	login alice
	password secret

Questions / comments:

FYI: username:fgets (stdin): Resource temporarily unavailable == UCSF VPN server problem

For your information

If you see a INFO: username:fgets (stdin): Resource temporarily unavailable message when trying to connect to the UCSF VPN, then it means that the UCSF VPN server is currently down.

Example

I got the following:

ucsf-vpn start
[sudo] password for hb: 
WARNING: Juniper Network Connect support is experimental.
It will probably be superseded by Junos Pulse support.
username:fgets (stdin): Resource temporarily unavailable
RESULT: Not connected to the UCSF VPN network (your public IP is 1.2.3.4)

I went to https://remote.ucsf.edu/ to check the online "VPN" and that also failed to log in (the error message was so quick it was not possible to catch it).

It all came back within 5 minutes.

Connected but not connected

I got the series of inconsistent indications about my connection status, as shown in the bottom. I was unable to connect for awhile, but the situation somehow resolved and I am connected now.

  1. connected via vpn (first command below) but then did not use the connection for about an hour.
  2. Then tried to RDP and got a message it couldn't reach the remote machine, usually an indication the connection is down.
  3. ucsf-vpn status said I was not connected (though it did report an openconnect process running).
  4. Yet a few seconds later when I tried to start it said I was already connected.
  5. Ran stop, seemingly without event.
  6. start then said "ERROR: Internet connection is not working".
  7. log reported no errors.
  8. start 9 minutes later succeeded. My RDP connection succeeded.

Speculation: if the connection is inactive it gets torn down, either on my side or the server. But this isn't a failure mode ucsf-vpn is familiar with.

Additionally, my connection has been unstable, periodically reporting it is disconnected and then automatically reconnecting, usually succeeding before timeout. The problem there may be on my end.

root@barley:~# date; ~ross/src/ucsf-vpn/bin/ucsf-vpn start  # 1 in the list above
Wed 28 Oct 2020 01:11:32 PM PDT
NOTE: Open the Duo Mobile app on your smartphone or tablet to confirm ...
OK: OpenConnect status: 'openconnect' process running (PID=8066)
DEBUG: running list-records in /etc/resolvconf/run/interface: enp5s0.inet
lo.named
tun0
OK: Public IP information: ip=128.218.42.217, hostname=, org=AS5653 University of California San Francisco
OK: Connected to the VPN

root@barley:~# date; ~ross/src/ucsf-vpn/bin/ucsf-vpn status # 3
Wed 28 Oct 2020 02:13:44 PM PDT
OpenConnect status: 'openconnect' process running (PID=8066)
Public IP information: ip=, hostname=, org=
Not connected to the VPN

root@barley:~# date; ~ross/src/ucsf-vpn/bin/ucsf-vpn start # 4
Wed 28 Oct 2020 02:13:56 PM PDT
WARNING: Skipping - already connected to the VPN
OK: OpenConnect status: 'openconnect' process running (PID=8066)
ERROR: Public IP information: ip=, hostname=, org= [ucsf-vpn 5.2.0-9000, OpenConnect 8.02-1+deb10u1]

root@barley:~# date; ~ross/src/ucsf-vpn/bin/ucsf-vpn stop # 5
Wed 28 Oct 2020 02:17:10 PM PDT
DEBUG: running list-records in /etc/resolvconf/run/interface: enp5s0.inet
lo.named
OK: OpenConnect status: No 'openconnect' process running
OK: Public IP information: ip=66.181.128.6, hostname=m128-6.dsl.rawbw.com, org=AS7961 Raw Bandwidth Communications, Inc.
OK: Not connected to the VPN

root@barley:~# date; ~ross/src/ucsf-vpn/bin/ucsf-vpn start # 6
Wed 28 Oct 2020 02:17:37 PM PDT
ERROR: Internet connection is not working [ucsf-vpn 5.2.0-9000, OpenConnect 8.02-1+deb10u1]

root@barley:~# date; ~ross/src/ucsf-vpn/bin/ucsf-vpn log # 7
Wed 28 Oct 2020 02:26:03 PM PDT
root@barley:~# date; ~ross/src/ucsf-vpn/bin/ucsf-vpn --verbose start # 8
Wed 28 Oct 2020 02:26:19 PM PDT
INFO: Pinging '9.9.9.9' once
INFO: Verified that internet connection works
INFO: Getting public IP (from https://ipinfo.io/ip)
INFO: Pinging '9.9.9.9' once
INFO: Preparing to connect to VPN server 'remote.ucsf.edu'
INFO: Administrative ("sudo") rights already establish
NOTE: Open the Duo Mobile app on your smartphone or tablet to confirm ...
INFO: Connecting to VPN server 'remote.ucsf.edu'
INFO: Connected to VPN server
INFO: validate='pid,ipinfo'
OK: OpenConnect status: 'openconnect' process running (PID=11699)
INFO: Pinging '9.9.9.9' once
DEBUG: running list-records in /etc/resolvconf/run/interface: enp5s0.inet
lo.named
tun0
INFO: Verified that internet connection works
INFO: Getting public IP (from https://ipinfo.io/ip)
OK: Public IP information: ip=128.218.43.45, hostname=, org=AS5653 University of California San Francisco
OK: Connected to the VPN

Pulse UI config: Connections are stored in a JSON file

It looks like the pulseUI connections are stored in ~/.pulse_secure/pulse/.pulse_Connections.txt:

{"connName": "ucsf", "preferredCert": "", "baseUrl": "https://remote.ucsf.edu/pulse"}
{"connName":"UCSF2","baseUrl":"https://another.ucsf.edu","preferredCert":""}
  • ucsf vpn troubleshoot could output these too.
  • ucsf vpn start --gui could use this to find which connection is for UCSF VPN; currently it assumes it is the first one and "TABs" accordingly.
  • ucsf vpn start --gui automatically appends a valid UCSF VPN connect, iff missing.
    Skipping:
  • ucsf vpn connection --list could parse and list them => ucsf vpn troubleshoot does this.
  • ucsf vpn connection --prepend/--append ucsf https://remote.ucsf.edu/pulse could be used to update the list => can easily be added in the GUI.
  1. ...

Reported hostname is empty

There is a function to extract the hostname out of the connection information. But I don't think there's anything to extract. The connection info comes from the following command, whose output appears below:

$ curl --silent https://ipinfo.io/json
{
  "ip": "128.218.192.91",
  "city": "San Francisco",
  "region": "California",
  "country": "US",
  "loc": "37.7758,-122.4130",
  "postal": "94103",
  "phone": "415",
  "org": "AS5653 University of California San Francisco"
}

So public_hostname, which greps for "hostname" is not going to find anything.

DOCUMENTATION: fgets (stdin): Inappropriate ioctl for device (=incorrect credentials)

I just noticed that you get the following obscure error message when you use a non-valid UCSF password:

$ ucsf vpn start
WARNING: Juniper Network Connect support is experimental.
It will probably be superseded by Junos Pulse support.
username:password:
fgets (stdin): Inappropriate ioctl for device
RESULT: Not connected to the UCSF network [ (172.56.38.241)]
$

Actions

  • Document this in ucsf vpn --help
  • Detect this error message and provide a more informative error message

Check for active PID before asking for token

Enter 'push', 'phone', 'sms', a 6 or 7 digit token, or press your YubiKey: <YubiKey token>
ERROR: Do you already have an active UCSF VPN connection? (Detected PID file '/home/hb/.config/ucsf-vpn/openconnect.pid'; if incorrect, remove with 'sudo rm /home/hb/.config/ucsf-vpn/openconnect.pid')

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.