haugene / vpn-configs-contrib

A collection of configs for various VPN providers
GNU General Public License v3.0
172 stars 739 forks source link

VPNUnlimited has changed their CA #261

Open SamJongenelen opened 6 months ago

SamJongenelen commented 6 months ago

Is there a pinned issue for this?

Is there an existing or similar issue for this?

Is there any comment in the documentation for this?

Is this related to the container/transmission?

Are you using the latest release?

Have you tried using the dev branch latest?

Config used

no options

Current Behavior

Tunnel wont work. I've contacted Keepsolid Inc and they told me their servers have indeed been supplied new certificates. We would need to regenerate the openvpn files

Expected Behavior

would connect.

How have you tried to solve the problem?

Contacted Keepsolid. They confirmed CA changed

Log output

2023-12-15 18:39:21 VERIFY ERROR: depth=2, error=self-signed certificate in certificate chain: C=US, ST=NY, L=New York, O=KeepSolid Inc., OU=KeepSolid Root CA, CN=KeepSolid Root CA, emailAddress=admin@keepsolid.com, serial=429164281094478856831696042475561970021707008630 2023-12-15 18:39:21 OpenSSL: error:0A000086:SSL routines::certificate verify failed 2023-12-15 18:39:21 TLS_ERROR: BIO read tls_read_plaintext error 2023-12-15 18:39:21 TLS Error: TLS object -> incoming plaintext read error 2023-12-15 18:39:21 TLS Error: TLS handshake failed

Environment

- OS: na
- Docker: na

Anything else?

provider VPNUnlimited has changed their CA. The OVPN files need updating, as currently we get errors while connecting

Yondz commented 6 months ago

Hi there,

Until this gets fixed on the repo (all .ovpn files must be updated), you can temporarily create your own updated .ovpn file and use custom provider in the configuration as explained in http://haugene.github.io/docker-transmission-openvpn/supported-providers/#using_a_local_single_ovpn_file_from_a_provider

What I did on my setup is this workaround :

  1. Copy the currently used .ovpn file from this repo and replaced \<ca> \<cert> and \<key> inside using the values from a freshly generated .ovpn file from vpnunlimited web account manager.
  2. Put this file in a folder on your host machine that will be mounted in your container to /etc/openvpn/custom as stated in the documentation.
  3. Change docker env var OPENVPN_PROVIDER to custom

Hope this helps :)

SamJongenelen commented 6 months ago

I was contemplating that, thanks for the steps! I'll try it tonight.

edit: worked like a charm. In my case, I was able to use the actual .ovpn file downloaded from the web account manager.

ArnaudScheffler commented 6 months ago

Hello,

I wrote this little script to download configurations for all VPNUnlimited servers. It's far from being perfect but it does the job. The only thing you need to do to use it is to retrieve the value of the php session cookie once you've logged in the web account manager.

# pip install requests
import requests

def get_device_ids(php_session: str):
    cookies = {'PHPSESSID': php_session}
    res = requests.get('https://my.keepsolid.com/api/account/config/devices/', cookies=cookies)
    json = res.json()
    return [x['uuid'] for x in json]

def get_region_ids(php_session: str):
    cookies = {'PHPSESSID': php_session}
    res = requests.get('https://my.keepsolid.com/api/account/config/regions/', cookies=cookies)
    json = res.json()
    return [x['id'] for x in json]

def get_config(region_id: str, php_session: str, device_id: str):
    cookies = {'PHPSESSID': php_session}
    params = {
        'deviceId': device_id,
        'region': region_id,
        'protocol': 'openvpn',
        'platform': 'win',
        'is_vps': 0
    }
    res = requests.get('https://my.keepsolid.com/api/account/config/', params=params, cookies=cookies)
    data = res.json()['download_data']
    # add ping-exit 30
    data = data.replace('ping 5\n', 'ping 5\nping-exit 30\n')
    # add auth-user-pass /config/openvpn-credentials.txt
    data = data.replace('remote-cert-tls server\n',
                        'remote-cert-tls server\nauth-user-pass /config/openvpn-credentials.txt\n')
    # add tls-cipher "DEFAULT:@SECLEVEL=0"
    data += '\ntls-cipher "DEFAULT:@SECLEVEL=0"'
    return data

if __name__ == '__main__':
    # Log in on https://my.keepsolid.com/products/vpn/ and get the PHPSESSID cookie value.
    # Use this value in the following variable
    session = '[CHANGE_ME]'
    devices = get_device_ids(session)
    if len(devices) < 1:
        raise Exception('No devices found. You must create a device in order to download the .ovpn files.')
    regions = get_region_ids(session)
    for region in regions:
        conf = get_config(region, session, devices[0])
        with open('../openvpn/vpnunlimited/' + region.replace('__', '-') + '.ovpn', 'w') as f:
            f.write(conf)

I can create a PR with all my files but I don't really understand how private they are. Are the cert and key attached to my account ?

SamJongenelen commented 6 months ago

Its exactly the reason i didnt do it. I am unsure which parts are private and which public .

Cool script btw

SensehacK commented 6 months ago

Can confirm, updating with custom config .ovpn file with CA certificates works now.

5nguy commented 6 months ago

Confirm. As the .ovpnfiles generated from VPNUnlimited don't contain any private information, a simple workaround is overwrite the .ovpnin the downloaded repo (openvpn) with the new one from the provider and mention the server in OPENVPN_CONFIG variable.

5nguy commented 6 months ago

Hello,

I wrote this little script to download configurations for all VPNUnlimited servers. It's far from being perfect but it does the job. The only thing you need to do to use it is to retrieve the value of the php session cookie once you've logged in the web account manager.

# pip install requests
import requests

def get_device_ids(php_session: str):
    cookies = {'PHPSESSID': php_session}
    res = requests.get('https://my.keepsolid.com/api/account/config/devices/', cookies=cookies)
    json = res.json()
    return [x['uuid'] for x in json]

def get_region_ids(php_session: str):
    cookies = {'PHPSESSID': php_session}
    res = requests.get('https://my.keepsolid.com/api/account/config/regions/', cookies=cookies)
    json = res.json()
    return [x['id'] for x in json]

def get_config(region_id: str, php_session: str, device_id: str):
    cookies = {'PHPSESSID': php_session}
    params = {
        'deviceId': device_id,
        'region': region_id,
        'protocol': 'openvpn',
        'platform': 'win',
        'is_vps': 0
    }
    res = requests.get('https://my.keepsolid.com/api/account/config/', params=params, cookies=cookies)
    data = res.json()['download_data']
    # add ping-exit 30
    data = data.replace('ping 5\n', 'ping 5\nping-exit 30\n')
    # add auth-user-pass /config/openvpn-credentials.txt
    data = data.replace('remote-cert-tls server\n',
                        'remote-cert-tls server\nauth-user-pass /config/openvpn-credentials.txt\n')
    # add tls-cipher "DEFAULT:@SECLEVEL=0"
    data += '\ntls-cipher "DEFAULT:@SECLEVEL=0"'
    return data

if __name__ == '__main__':
    # Log in on https://my.keepsolid.com/products/vpn/ and get the PHPSESSID cookie value.
    # Use this value in the following variable
    session = '[CHANGE_ME]'
    devices = get_device_ids(session)
    if len(devices) < 1:
        raise Exception('No devices found. You must create a device in order to download the .ovpn files.')
    regions = get_region_ids(session)
    for region in regions:
        conf = get_config(region, session, devices[0])
        with open('../openvpn/vpnunlimited/' + region.replace('__', '-') + '.ovpn', 'w') as f:
            f.write(conf)

I can create a PR with all my files but I don't really understand how private they are. Are the cert and key attached to my account ?

Nice script. I see some VPN providers publishing these certificate and key. You can also see these informations in the existing vnpunlimited .opvn . What is private, in my opinion is the login information that are given separately.

Otherwise, I see that your script uses id var from regions json instead of region as id is unique ID but not region (can have more than one server). In other provider folder, some use region with multiple remote servers in .opvn file when a region has more than one id(servers). I think your script is better by using unique idf or each server.