Jigsaw-Code / outline-apps

Outline Client and Manager, developed by Jigsaw. Outline Manager makes it easy to create your own VPN server. Outline Client lets you share access to your VPN with anyone in your network, giving them access to the free and open internet.
https://getoutline.org/
Apache License 2.0
8.38k stars 1.36k forks source link

will it support subscription link? #215

Open TheCGDF opened 6 years ago

TheCGDF commented 6 years ago

hello, in chinese, we in common use subscription to update the shadowsocks servers from merchant because GFW often bans the server. so, i want to know will this app support subscription link?

trevj commented 6 years ago

@SoDa-GitHub Thanks for trying Outline. I'm not sure I understand: this is a service which automatically moves a server from IP to IP?

TheCGDF commented 6 years ago

1.user pay for service 2.user get a private subscription link (http://xxxxx) 3.user copy and paste the link in the software which support subscription (such as ShadowsocksR/ShadowsocksRR/Quantumult/Shadowrocket) 4. while(true){ software use the link to get the server list and something else. ( it can be a set of ss://) software use the data returned by the link to update the server list sleep(a short time) }

ghost commented 6 years ago

I think it's a good way to auto configure client. Problem is how to integrate it into outline-server. And is it standardized?

TheCGDF commented 6 years ago

i don't think it's difficult to write code. and SSR subscription link has been standardized in china for many years. i'm not sure whether the project will accept subscription. i'm a developer of ss-panel-v3-mod_Uim project. this project is the most popular Shadowsocks Service Shop Template in china. almost all chinese merchant support SSR subscription standard.

TheCGDF commented 6 years ago

however, SSR subscription contains some info about obfs, which sometimes is not supported by Shadowsocks. and we are beginning to spread SSD subscription, which is used to replace SSR subscription. SSD subscription uses a json text encrypted by BASE64, for example:

{
    "airport":"sspanel",    //airport name (in china, this service is called 'airport'
    "port":39694,   //airport default port
    "encryption":"rc4-md5",
    "password":"3dmrbK",
    "servers":  //server list
    [
        {
            "id":9, //server ID (it can be used to sort, or dismiss)
            "server":"www.baidu.com", //server address or ip
            "remarks":"uu", //
            "ratio":1   //traffic ratio
        },
        {
            "id":10,
            "server":"i.com",
            "remarks":"ii",
            "ratio":1,
            "port":1233 //not use default port
        }
    ]
}
ghost commented 6 years ago

@trevj This is a client auto configure standard designed by commercial shadowsocks service providers. It can configure new server when old one got banned, and it can configure multiple server at one time. Maybe you need this for server cluster and load balance in the future. I suggest add (partial or modified) support for client, when we can set multiple server, it will be useful.

trevj commented 6 years ago

@studentmain Thanks for the explanation!

OneHappyForever commented 5 years ago

Put simply:

The subscribe link: a url (basically a RESTful API) that returns a list of servers in ss:// format (usually from a backend database)

All you need to do is: read the output from the URL (usually it's in base64 format), and parse each server (i.e. by ss://). Then, input the servers (maybe use a foreach loop).

Any ETA?

Edit: if you need an example of a working subscribe link that outputs ss:// links, let me know and I can provide you one via email/pm)

mrcao commented 1 week ago

Hi! I recently moved to China and want to echo this feature request. I am currently using something else, but Claude recommended this and based on the creators it looks very solid and will likely remain supported for a long time.

Claude has provided this script for me to decode the subscription links, which is a simple CLI tool that takes in a subscription link. Below the code is a clear explanation for the big picture context. I supply this code for you to get an idea of how simple it ultimately is, though you might want to capture the server configs in a useful format rather than just print to console. (And course anyone is free to use this code for whatever reason)

import base64
import urllib.parse
import requests
import re

def fetch_and_decode_subscription(url):
    response = requests.get(url)
    if response.status_code != 200:
        raise Exception(f"Failed to fetch subscription. Status code: {response.status_code}")

    decoded_content = base64.b64decode(response.text).decode('utf-8')
    return decoded_content

def safe_base64_decode(s):
    """Decode base64, padding being optional."""
    s = str(s).strip()
    try:
        return base64.urlsafe_b64decode(s + '=' * (4 - len(s) % 4))
    except Exception:
        return None

def decode_ss_url(ss_url):
    # Remove the 'ss://' prefix
    encoded_str = ss_url.split('://')[1]

    # Split the string at the @ symbol
    parts = encoded_str.split('@')

    if len(parts) == 1:
        # If there's no @, everything is base64 encoded
        decoded = safe_base64_decode(encoded_str)
        if decoded is None:
            raise ValueError("Failed to decode base64 string")
        decoded = decoded.decode('utf-8')
        method, password = decoded.split(':')
        host, port = '', ''
    else:
        # If there's an @, the first part is base64 encoded
        decoded = safe_base64_decode(parts[0])
        if decoded is None:
            raise ValueError("Failed to decode base64 string")
        decoded = decoded.decode('utf-8')
        method, password = decoded.split(':')
        host, port = parts[1].split(':')

    # The last part might contain a tag after #
    if '#' in port:
        port, tag = port.split('#')
        tag = urllib.parse.unquote(tag)
    else:
        tag = ''

    return {
        'method': method,
        'password': password,
        'host': host,
        'port': port,
        'tag': tag
    }

def format_ss_urls(input_str):
    # Split the input string into individual SS URLs
    ss_urls = re.findall(r'ss://[^\s]+', input_str)

    formatted_output = []
    for i, url in enumerate(ss_urls, 1):
        try:
            decoded = decode_ss_url(url)
            formatted_output.append(f"Server {i}:")
            formatted_output.append(f"  Method: {decoded['method']}")
            formatted_output.append(f"  Password: {decoded['password']}")
            formatted_output.append(f"  Host: {decoded['host']}")
            formatted_output.append(f"  Port: {decoded['port']}")
            if decoded['tag']:
                formatted_output.append(f"  Tag: {decoded['tag']}")
            formatted_output.append("")
        except Exception as e:
            formatted_output.append(f"Error decoding URL {i}: {str(e)}")
            formatted_output.append("")

    return "\n".join(formatted_output)

def main():
    subscription_url = input("Enter the subscription URL: ")
    try:
        decoded_content = fetch_and_decode_subscription(subscription_url)
        formatted_output = format_ss_urls(decoded_content)
        print("\nFormatted SS URLs:")
        print(formatted_output)
    except Exception as e:
        print(f"An error occurred: {str(e)}")

if __name__ == "__main__":
    main()

Understanding Chinese Subscription Links for VPN Services

What are Subscription Links?

Subscription links are a convenient method used by many VPN services, particularly those catering to users in China and other regions with internet restrictions. These links provide an easy way for users to obtain and update their VPN server configurations.

Since China's relation with VPNs (which aren't illegal strictly speaking) is a whack-a-mole/cat-and-mouse game, these subscription links with a large amount of specific server configurations are able to keep the relation/function between the user/client and the VPN/Node provider stable even if the specific nodes used will vary a lot: servers often change in availability and are updated accordingly over time, so it doesn't make sense for these users to restrict themselves to one server config.

Format and Usage

  1. Format: A typical subscription link looks like this: http://example.com/sub?token=abcdef123456

  2. Content: When accessed, this link returns a Base64 encoded string. When decoded, this string contains multiple Shadowsocks server configurations, each in the format: ss://[method:password@]hostname:port#tag

  3. Usage: VPN clients that support subscription links can periodically fetch and update their server list from this URL, ensuring users always have access to the most current and functional servers.

Relation to Shadowsocks

Shadowsocks is a popular protocol for bypassing internet censorship. The subscription link mechanism was developed to work seamlessly with Shadowsocks, although it's not exclusive to this protocol. Each line in the decoded subscription content represents a single Shadowsocks server configuration.

Importance for Internet Freedom in China

  1. Ease of Use: Users don't need to manually configure servers. They can simply input the subscription link into their VPN client.

  2. Dynamic Updates: VPN providers can easily add, remove, or change servers without requiring user action.

  3. Bypass Blocking: If a server is blocked, providers can quickly update the subscription with new, unblocked servers.

  4. Reduced User Error: Minimizes the chance of misconfiguration, which is crucial when every connection attempt might be monitored.

  5. Flexibility: Allows users to switch between multiple servers easily, improving chances of maintaining a stable connection.

Implementation in Outline

Adding support for these subscription links in Outline would be a significant feature for users in restricted internet environments. It would allow them to:

  1. Easily import and update multiple server configurations.
  2. Quickly adapt to changing censorship measures.
  3. Benefit from the wide ecosystem of existing Shadowsocks servers and providers.

This feature would make Outline more versatile and user-friendly for those who need it most, reinforcing its role in promoting internet freedom globally.


Hope you may consider the feature! I think it will be a very simple feature to implement with great value for a country that needs these things the most.