Skip to content

Core proxying component of the Lantern censorship circumvention tool.

License

Notifications You must be signed in to change notification settings

getlantern/flashlight

Folders and files

NameName
Last commit message
Last commit date

Latest commit

a139942 · Oct 18, 2022
Nov 2, 2020
Sep 9, 2022
Oct 12, 2022
Jan 6, 2021
Sep 28, 2022
Apr 30, 2021
Oct 9, 2018
Apr 30, 2021
Sep 7, 2022
Oct 13, 2022
Oct 12, 2022
Jul 23, 2022
Oct 18, 2022
Aug 19, 2022
Aug 19, 2022
Sep 7, 2022
Sep 22, 2022
Sep 22, 2022
Mar 7, 2020
Mar 11, 2022
Oct 4, 2022
Oct 18, 2022
Sep 12, 2022
Aug 19, 2022
Sep 16, 2019
Oct 1, 2022
Aug 8, 2022
Oct 4, 2022
Oct 11, 2017
Oct 4, 2022
Aug 19, 2022
Jan 11, 2022
Jun 23, 2022
Feb 3, 2022
Aug 8, 2022
Sep 13, 2022
Oct 15, 2022
Nov 12, 2018
Oct 22, 2021
May 25, 2021
Nov 18, 2020
Sep 2, 2016
Feb 7, 2020
Jan 24, 2022
Jun 10, 2021
Nov 27, 2020
Jun 3, 2021
Dec 16, 2021
Oct 10, 2022
Oct 18, 2022
Aug 19, 2022
Oct 10, 2022
Sep 12, 2021
Oct 13, 2022
Oct 13, 2022
May 3, 2018

Repository files navigation

Lantern Go Actions Status Coverage Status

This repo contains the core Lantern library as well as the Android and iOS bindings.

The Lantern desktop application can be found at getlantern/lantern-desktop.

Process for making changes to config

flashlight is configured with per-proxy configuration loaded from the config-server, and global configuration loaded from S3 at runtime.

The global configuration is generated by genconfig running as a CRON job on cm-donyc3021etc. That job uses the latest version of genconfig that is pushed to releases in this repo via CI.

genconfig merges embeddedconfig/global.yaml.tmpl with dynamically verified masquerade hosts to produce the final global config. embeddedconfig/download_global.sh pulls in that change and runs anytime we run go generate. A CI Job runs go generate and automatically commits the results to this repo.

All clients, including old versions of flashlight, fetch the same global config from S3, so global.yaml.tmpl must remain backwards compatible with old clients.

If you're simply changing the contents of global.yaml.tmpl without any structural changes to the Go files in config, you can just change global.yaml.tmpl directly and once it's committed to main, it will fairly soon be reflected in S3.

If you're making changes to structure of the configuration, you need to ensure that this stays backwards compatible with old clients. To this end, we keep copies of old versions of config, for example config_v1. When making a structural change to the config, follow these steps:

  1. Back up the current version of config, for example cp -R config config_v2
  2. Update the code and tests in config as appropriate
  3. Make sure the tests in config_v2, config_v1 etc. still work

Adding new domain fronting mappings

In addition to adding the domains that forward on Cloudfront and Akamai, you also have to add the appropriate lines to this.

Mappings on Cloudfront and Akamai can be added using the terraform config in lantern-cloud.

Building

You can build an SDK for use by external applications either for Android or for iOS.

Prerequisites

  • Go 1.18 is the minimum supported version of Go
  • GNU Make if you want to use the Makefile
  • Dependencies are managed with Go Modules.
  • Force git to use ssh instead of https by running git config --global url."git@github.com:".insteadOf "https://github.com/"

Android SDK

make lanternsdk-android.aar

iOS SDK

make Lanternsdk.xcframework

iOS SDK Usage

The below shows how to start Lantern and use it. When iOS puts the hosting app the sleep and wakes it up again, Lantern's proxy listener will hang because the socket becomes unconnected but Go doesn't notice it. So it's necessary to call LanternsdkStart every time the app wakes, which will start a new listener and return its new address.

A good place to do this is in applicationDidBecomeActive, which is called when the app first starts and every time it wakes.

import Lanternsdk

...

let configDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent(".lantern")
let deviceID = UIDevice.current.identifierForVendor!.uuidString

var error: NSError?
let proxyAddr = Lanternsdk.LanternsdkStart("TestApp",
                            configDir.path,
                            deviceID,
                            true, // proxyAll
                            60000, // start timeout
                            &error)
if let err = error {
    throw err
}

if let host = proxyAddr?.httpHost {
    if let port = proxyAddr?.httpPort {
        let proxyConfig = URLSessionConfiguration.default
        // see https://stackoverflow.com/questions/42617582/how-to-use-urlsession-with-proxy-in-swift-3#42731010
        proxyConfig.connectionProxyDictionary = [AnyHashable: Any]()
        proxyConfig.connectionProxyDictionary?[kCFNetworkProxiesHTTPEnable as String] = 1
        proxyConfig.connectionProxyDictionary?[kCFNetworkProxiesHTTPProxy as String] = host
        proxyConfig.connectionProxyDictionary?[kCFNetworkProxiesHTTPPort as String] = port
        proxyConfig.connectionProxyDictionary?[kCFStreamPropertyHTTPSProxyHost as String] = host
        proxyConfig.connectionProxyDictionary?[kCFStreamPropertyHTTPSProxyPort as String] = port

        let session = URLSession.init(configuration: proxyConfig)
        // you can now use this session and everything is proxied
    }
}

TestApp

lanternsdk/TestApp contains a test iOS application demonstrating use of the lanternsdk on iOS.

A note on iOS and memory usage

The iOS application needs to run as a background process on iOS, meaning that it's severely memory restricted. Because of this, we disable a lot of protocols and extra features using // +build !iosapp in order to conserve memory.

Why not use // +build !ios

go-mobile automatically sets the ios build tag when building for iOS. In our case, we don't use this because in addition to the iOS app, we also distribute an iOS SDK that's intended for embedding inside of user-interactice apps. This SDK does not have to run in the background and is thus not memory constrained in the same way as our iOS app. Consequently, the sdk can and does include all of the standard lantern protocols and features.

Architecture

Overview

Features

We use "features" to enable/disable different characteristics/techniques in Flashlight, usually through the global config.

See ./config/features.go for a list of features. Below is a non-extensive description of each feature.

p2pcensoredpeer and p2pfreepeer

Allows the client to act either as a FreePeer or a CensoredPeer.

See overview of the p2p-proxying story here: https://docs.google.com/document/d/1JUjZHgpnunmwG3wUwlSmCKFwOGOXkkwyGd7cgrOJzbs/edit