IPv6 in AnyConnect for iOS

sskaje sskaje at gmail.com
Fri Dec 26 00:51:50 PST 2014


Hi, I'm trying to make my iPhone work with IPv6, I can't find any
details on anyconnect using ipv6, so I just try to debug and make some
changes on ocserv.
I need someone tell me if I was in a wrong track or ocserv ipv6 is buggy.


I asked Linode for an ipv6 address pool, set the options like

ipv6-network = 2400:8900:e000:xxxx::
ipv6-prefix = 64

But clients generate fake IPv6 addresses(Debug logs in AnyConnect iOS).

I add debug log in cstp_send(), see what's sent to the client, no IPv6
address found, but in the debug log:

ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 new cookie for 'sskaje' (1359)
ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 accepting user 'sskaje'
ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 selected IP for
'sskaje': 192.168.122.198
ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 selected IP for
'sskaje': 2400:8900:e000:xxxx:xxxx:2f:f9e5:c700
ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 assigned IPv4 to
'sskaje': 192.168.122.199
ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 assigned IPv6 to
'sskaje': 2400:8900:e000:xxxx:xxxx:2f:f9e5:c701
ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 assigning tun device vpns0
ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 user 'sskaje' of group
'vpn' authenticated (using cookie)
ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 sending dns '8.8.8.8'
ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 sending dns '8.8.8.8'
ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 sending dns '8.8.4.4'
ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 sending (socket) message
2 to worker

ifconfig on my Ubuntu VPS, the c700 IP is assigned to the vpns0, but
c701 not ping6-able.


In worker-vpn.c, I found

    if (ws->vinfo.ipv6 && req->no_ipv6 == 0) {

has no_ipv6 == 1, So I added extra User Agent matching like:

        if (strncasecmp(req->user_agent, "Open Any", 8) == 0) {
            if (strncmp(req->user_agent, "Open AnyConnect VPN Agent
v3", 28) == 0)
                req->user_agent_type = AGENT_OPENCONNECT_V3;
            else
                req->user_agent_type = AGENT_OPENCONNECT;
        } else if (strncasecmp(req->user_agent, "Cisco AnyConnect", 16) == 0) {
            req->user_agent_type = AGENT_ANYCONNECT;
        }
        break;

And then

    /* If we are in CISCO client compatibility mode, do not send
     * any IPv6 information, unless the client can really handle it.
     */
    if (ws->full_ipv6 == 0 && ws->config->cisco_client_compat != 0 &&
        req->user_agent_type != AGENT_OPENCONNECT &&
req->user_agent_type != AGENT_ANYCONNECT) {
        req->no_ipv6 = 1;
    }

But ws->full_ipv6 is still 0, and TWO X-CSTP-Address lines are sent to
client, with both IPv4 and IPv6 addresses.
Logs:

ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  HTTP/1.1 200 CONNECTED
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-CSTP-Version: 1
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-Server-Version: ocserv 0.8.9
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-CSTP-DPD: 90
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-CSTP-Default-Domain: sskaje.me
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-CSTP-Address: 192.168.122.199
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-CSTP-Netmask: 255.255.255.0
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-CSTP-Address: 2400:8900:e000:xxxx:xxxx:2f:f9e5:c701
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-CSTP-DNS: 8.8.8.8
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-CSTP-DNS: 8.8.8.8
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-CSTP-DNS: 8.8.4.4
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-CSTP-Keepalive: 32400
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-CSTP-Idle-Timeout: none
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-CSTP-Smartcard-Removal-Disconnect: true
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-CSTP-Rekey-Time: 172800
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-CSTP-Rekey-Method: ssl
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-CSTP-Session-Timeout: none
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-CSTP-Base-MTU: 1435
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-DTLS-Session-ID: --------
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-DTLS-DPD: 90
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-DTLS-Port: 8443
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-DTLS-Rekey-Time: 172810
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-DTLS-Rekey-Method: ssl
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-DTLS-Keepalive: 32400
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-DTLS-CipherSuite: AES128-SHA
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-DTLS-MTU: 1341
ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER:
  X-CSTP-MTU: 1341


I guess if it is because the full_ipv6 0, then I force it 1 for AnyConnect:
    if (req->user_agent_type == AGENT_ANYCONNECT) {
        ws->full_ipv6 = 1;
    }

found ws->vinfo.ipv6_prefix == 0, fixed in worker-auth.c:

static int recv_cookie_auth_reply(worker_st * ws)
...
            if (msg->ipv6_prefix) {
                ws->config->network.ipv6_prefix = msg->ipv6_prefix;
            }
...


And the ws->vinfo.ipv6_network is also null, from
recv_cookie_auth_reply() both ws->config->network.ipv6_network and
msg->ipv6_prefix are null.
In config.c, ipv6-network options is read into config->network.ipv6.

I'm totally lost.



sskaje at gmail.com
https://sskaje.me/



More information about the openconnect-devel mailing list