Build your own customized Android OS for Google Pixel phones using AWS cloud infrastructure. The default OS that this tools builds without any customizations is called RattlesnakeOS
. If there is something you don't like about the default OS, you can add customizations on top of it or start with a completely blank slate and build your own OS.
The default OS built by this tool, RattlesnakeOS
, is just stock AOSP and has all the baseline privacy and security features from there. Unlike other alternative Android OSes, it aims to keep security on par with stock Android by keeping critical security features like verified boot enabled and ensuring monthly OTA security updates not only update the OS but also the device specific drivers and firmware.
Rather than providing random binaries of an Android OS to install on your phone, I've gone the route of creating a cross platform tool, rattlesnakeos-stack
, that provisions a "stack", which is just all the AWS cloud infrastructure needed to continuously build your own personal Android OS, with your own signing keys, and your own OTA updates. It uses AWS Lambda to provision EC2 spot instances that build the OS and upload artifacts to S3. Resulting OS builds are configured to receive over the air updates from this environment. It only costs a few dollars a month to run (see FAQ for detailed cost breakdown).
Launch instance
, select any OS, pick a c5.4xlarge
, and click Review and launch
. After it launches successfully you can terminate the instance through the console. If you can't launch an instance of this size with your new account, you may need to request a limit increase through the web console for that instance type.AdministratorAccess
access. If you're not sure how to do that, you can follow this step by step guide. You'll need the generated AWS Access Key and Secret Key for the next step.rattlesnakeos
in AWS. The public and private SSH key will be dumped to the current directory, make sure to save these to a safe place.keypair_name="rattlesnakeos"
ssh-keygen -t rsa -b 4096 -f ${keypair_name}
for region in $(aws ec2 describe-regions --query "Regions[*].RegionName" --output text); do
echo "Importing keypair ${keypair_name} to region ${region}..."
aws ec2 import-key-pair --key-name "${keypair_name}" --public-key-material "fileb://${keypair_name}.pub" --region $region
done
The rattlesnakeos-stack
tool needs to be installed on your local computer. The easiest way is to download a pre-built binary from the Github Releases page. The other option is to build from source.
The rattlesnakeos-stack config
subcommand should be run first to initialize a config file which will be stored in $HOME/.rattlesnakeos.toml
. By default, an autogenerated stack name will be generated for <rattlesnakeos-stackname>
; if you want to customize this name beware that the name must be globally unique in AWS or deployment will fail.
./rattlesnakeos-stack config
Device is the device codename (e.g. sunfish).
device: sunfish
Stack name is used as an identifier for all the AWS components that get deployed. THIS NAME MUST BE UNIQUE OR DEPLOYMENT WILL FAIL.
Stack name: <rattlesnakeos-stackname>
Stack region is the AWS region where you would like to deploy your stack. Valid options: us-west-2, us-east-1, us-east-2, us-west-1, eu-west-1, eu-west-2, eu-west-3, ap-northeast-3, ap-northeast-2, ap-northeast-1, sa-east-1, ap-southeast-1, ca-central-1, ap-southeast-2, ap-south-1, eu-central-1, cn-north-1, cn-northwest-1
Stack region: us-west-2
Email address you would like to send build notifications to.
Email: user@domain.com
SSH keypair name is the name of your EC2 keypair that imported into AWS.
SSH Keypair Name: rattlesnakeos
INFO[0005] rattlesnakeos-stack config file has been written to /Users/username/.rattlesnakeos.toml
The rattlesnakeos-stack deploy
subcommand handles deploying (and updating) your stack. After stack deployment, you will need to manually start a build. By default, it is configured to automatically build once a month on the 10th of the month so that monthly security updates can be picked up and built without the need for manual builds. Anytime you make a config change, you will first need to deploy those changes using this command before starting a new build.
Deploy stack using default generated config file:
./rattlesnakeos-stack deploy
INFO[0000] Using config file: /Users/user/.rattlesnakeos.toml
INFO[0000] Current settings:
chromium-version: ""
device: taimen
email: user@domain.com
hosts-file: ""
instance-regions: us-west-2,us-west-1,us-east-2
instance-type: c5.4xlarge
max-price: "1.00"
name: <rattlesnakeos-stackname>
region: us-west-2
schedule: rate(14 days)
skip-price: "0.68"
ssh-key: rattlesnakeos
Do you want to continue? [y/N]
You can override values in the config file with CLI flags:
./rattlesnakeos-stack deploy --region "us-west-2"
...
You can also persist values you override to the config file if desired:
./rattlesnakeos-stack deploy --region "us-west-2" --save-config
...
Or you can specify a different config file to use
./rattlesnakeos-stack deploy --config-file foo.toml
...
To see full list of options you can run rattlesnakeos-stack deploy -h
. These flags can also be set as config values in the config file.
Here is an example of a more advanced config file that: disables chromium build (warning: if you do this - you should provide your own up to date webview), disables scheduled monthly builds, specifies a custom configuration repo (more on that in customization section), and uses a much larger c5.24xlarge instance type.
chromium-build-disabled = true
chromium-version = ""
cloud = "aws"
core-config-repo = "https://github.com/rattlesnakeos/core"
custom-config-repo = "https://github.com/myrepo/custom"
device = "sunfish"
email = "dan@vittegleo.com"
instance-regions = "us-west-2,us-west-1,us-east-2"
instance-type = "c5.24xlarge"
latest-url = "https://raw.githubusercontent.com/RattlesnakeOS/latest/11.0/latest.json"
max-price = "5.00"
name = "sunfish-cyoydyw3j2"
region = "us-east-2"
schedule = ""
skip-price = "5.00"
ssh-key = "rattlesnakeos"
Click on the email confirmation link sent to your email in order to start getting build notifications.
You'll need to manually start your first build using rattlesnakeos-stack
tool. Future builds will happen automatically based on the schedule defined in your configuration.
./rattlesnakeos-stack build start
You should get email notifications that your build has started. If you didn't get an email notification with the details of where it launched, you can use the CLI to list active builds.
./rattlesnakeos-stack build list
The initial build will likely take 7+ hours to complete. Looking at the EC2 instance metrics like CPU, etc is NOT a good way to determine if the build is progressing. See the FAQ for details on how to monitor live build progress.
After the build finishes, a factory image should be uploaded to the S3 release bucket that you can download. Be sure to replace the command below with your stack name and your device name (e.g. sunfish).
aws s3 cp s3://<rattlesnakeos-stackname>-release/<device>-factory-latest.zip .
Use this factory image and follow the instructions on flashing your device carefully.
After successfully flashing your device, you will now be running RattlesnakeOS and all future updates will happen through the built-in OTA updater.
I HIGHLY suggest backing up your generated signing keys and storing them somewhere safe. To back up your signing keys:
aws s3 sync s3://<rattlesnakeos-stackname>-keys/ .
It is possible to customize OS builds to your liking by specifying a custom config repo with the config option custom-config-repo = "https://github.com/yourrepo/name"
. This git repo needs to adhere to a specific format that will be covered below.
IMPORTANT: using any Git repo here that is not in your control is a security risk, as you are giving control of your build process to the owner of the repo. They could steal your signing keys, inject malicious code, etc.
The custom config git repo needs to be laid out in a specific format to work with the build process. An example repo can be found here: https://github.com/RattlesnakeOS/example-custom-config-repo. The directory structure looks like this:
hooks/
local_manifests/
vendor/
hooks
- this directory can contain shell scripts that can hook into the build process at various steps along the way. There are pre
and post
entry points. The shell scripts need to be named <build_function_function_to_hook>_<pre|post>.sh
(e.g. aosp_build_pre.sh). Right now these hooks scripts are sourced in a subshell, so all environment variables from the core build script are available to these hooks (e.g. AOSP_BUILD_DIR, etc), but it's best to limit environment dependencies, as backwards compatibility is not guaranteed as the core build script changes.local_manifests
- this is a directory for local AOSP manifests to be placed. These manifests will be synced to the AOSP build tree.vendor
- is a place to override vendor configuration. You can make use of the support for AOSP overlays to easily modify configuration settings. Under the vendor
directory, there needs to be a mk file at config/main.mk
.Use this at your own risk.
Just download the new version of rattlesnakeos-stack and run deploy again (e.g. ./rattlesnakeos-stack deploy)
If you go to Settings -> System -> Advanced (to expand) -> System update settings
, you'll see the updater app settings. The updater app will check S3 to see if there are updates and if it finds one will download and apply it your device.
I only have access to a single device and carrier to test this on, so I can't make any promises about it working with your specific carrier. Confirmed working: T-Mobile, Rogers, Cricket, Ting. Likely not to work: Sprint (has requirements about specific carrier app being on phone to work), Project Fi.
Building AOSP and Chromium requires a fairly powerful server, which is not something everyone readily has access to. Using a cloud provider allows you to spin up compute resources capable of building these projects and only paying for the time you use them. It could really be any cloud provider, but just happened to choose AWS. There are pros and cons to building AOSP in the cloud. On the positive side, cloud providers allow you to easily write automation that can spin up and down resources as needed which allows rattlesnakeos-stack to automate the entire process of building an Android OS and distributing OTA updates. On the downsides, for those that are very security conscious, they may be wary of building an OS on shared cloud resources. You can check out the security section of the FAQ for more details on this.
It's not likely that other devices will be supported beyond the Google Pixel line. Here are some reasons:
No. RattlesnakeOS was created initially as an alternative to CopperheadOS, a security hardened Android OS created by Daniel Micay, after it stopped being properly maintained back in June 2018. To be clear, this project is not attempting to add or recreate any of the security hardening features that were present in CopperheadOS. If you are interested in the continuation of the CopperheadOS project you can check out GrapheneOS.
The costs are going to be variable by AWS region and by day and time you are running your builds, as spot instances have a variable price depending on market demand. Below is an example scenario that should give you a rough estimate of costs:
max-price
config value to set the max price you are willing to pay and if market price exceeds that then your instance will be terminated. Builds can take anywhere from 3-7 hours depending on if Chromium needs to be built. So let's say you're doing a build every month at $0.50 an hour, and it is taking on average 4 hours - you'd pay ~$2 in EC2 costs per month.By default, it is configured to automatically build once a month on the 10th of the month so that monthly updates can be picked up and built without the need for manual builds. There is a config option to specify how frequently builds are kicked off automatically. For example you could set schedule = "rate(14 days)"
in the config file to build every 14 days. Also note, the default behavior is to only run a build if there have been version updates in stack, AOSP, or Chromium versions.
You can manually kick off a build with the CLI. Note that this shouldn't normally be necessary as builds are set to happen automatically on a cron schedule.
./rattlesnakeos-stack build start
On build failure/success, the instance should terminate and upload its logs to S3 bucket called <rattlesnakeos-stackname>-logs
and it's in a file called <device>/<timestamp>
.
There are a few steps required to be able to do this:
ssh -i yourprivatekey ubuntu@yourinstancepublicip
tail -f /var/log/cloud-init-output.log
If there wasn't an error notification, this is likely because the Spot Instance max price was not high enough or EC2 is low on capacity and needs to reclaim instances. You can see historical spot instance pricing in the EC2 console. Click Pricing History
, select c5.4xlarge for Instance Type
and pick a date range.
Your ability to secure your signing keys determines how secure RattlesnakeOS is. RattlesnakeOS generates and stores signing keys in AWS, which means the security of your AWS account becomes critical to ensuring the security of your device. If you aren't able to properly secure your local workstation, and your AWS account, then these additional security protections like verified boot become less useful.
Cloud based builds are never going to be as secure as a locally built AOSP signed with highly secured keys generated from an HSM or air gapped computer, so if this is the level of security you require then there really is no other way. Would I recommend cloud builds like this for a large OEM or a company like CopperheadOS where the signing key being generated is protecting thousands of users? No, this becomes a high profile target as getting a hold of these keys essentially gives an attacker access to thousands of devices. On the other hand, for a single user generating their own key protecting a single device, there is less concern in my mind unless your threat profile includes very targeted attacks.
Some minimum steps worth considering are having an account solely for building RattlesnakeOS with a strong password, enabling two-factor authentication, enabling auditing with CloudTrail, and locking down access to your AWS API credentials.
If you decide this isn't for you and you want to remove all the provisioned AWS resources, there's a command for that.
./rattlesnakeos-stack remove --name <rattlesnakeos-stackname> --region us-west-2
IMPORTANT NOTE: this will not terminate any running EC2 instances that may have launched, and these will need to be terminated manually.
You'll need to clear the configured AVB public key after unlocking the bootloader and before locking it again with the stock factory images.
fastboot erase avb_custom_key
git clone github.com/dan-v/rattlesnakeos-stack
make tools
make
1.中文翻译叫做堆栈跟踪,一个调试工具,或者叫做调试方法。 它的展示方式就是线程和JVM监测的snapshot,根据程序的复杂程度,它可能有几十行到几千行不等。 在try-catch语句中,每当catch到了Exception,通常默认的做法就是printStackTrace。其实一共有3个方法生成stack trace,这个貌似是最普遍的方法。 2.打印出来了以后该怎么看呢? 首先,找到当前的线
5.Stack:什么是Stack和Stack的特点是什么???Stack独有哪三种方法??? 学习:第7遍 1.什么是Stack和Stack的特点是什么??? Stack继承自Vector 栈特点:先进后出 2.Stack独有哪三种方法??? 常用方法:具有List的所有方法 同时具有栈独有操作方法 方法一:stack.push(“先进去的小王”) 作用:入栈或压栈 方法二:stack.pop()
PATers believe that wearing hats makes them look handsome, so wherever they go, everyone of them would wear a hat. One day they came to a restaurant, a waiter collected their hats and piled them up. B
Stack public class Stack<E> extends Vector<E> Stack是Vector的子类,是一个标准的先进后出的栈。 Stack有几个自己特有的方法。 Modifier and Type Method and Description boolean empty() Tests if this stack is empty. E peek() Looks at
对于Stack类的实现,跟之前链表实现也一样,只是封装成为面向对象的类了 PS:这里是线式存储的类和模板实现,链表式的实际上写法也是一样的 class Stack代码如下: mystack.h #include<stdlib.h> #include<stdio.h> struct Stack { int _len; int _top; char *
torch.stack() 是 PyTorch 中的一个函数,用于将多个张量沿着新的维度进行堆叠。具体而言,torch.stack(seq, dim=0) 执行以下操作: 将 seq 序列中的每个张量视为一行,构建一个新的二维张量(即矩阵),其中第 i i i 行对应于第 i i i 个张量; 在指定的 dim 维度上对这些行进行堆叠,从而得到一个新的张量。 例如,假设有两个形状为 [3] 的张量
7. Write a program that reads in a sequence of characters and prints them in reverse order. Use a stack. STACK 定义,pop(),push()函数定义 stack = [None for index in range(0, 10)] basePointer = 0 topPoin
问题内容: 我正在阅读Java文章,但在声明中没有发现差异,因此感到困惑。有人可以列出我吗? 添加了文章 http://www.theparticle.com/javadata2.html 问题答案: 关于问题的确切含义,我没有更多细节,我将回答问题的标题, 创建一个: 创建一个: 这意味着,创建的和对象。您 _ 不能_ 使用,因为那是原始数据类型,请参阅链接以获取原始数据类型的列表。 创建一个:
问题内容: 如何用Java 处理? 问题答案: 我不确定“句柄”是什么意思。 您当然可以捕获该错误: 但这很可能是个坏主意,除非您确切地知道自己在做什么。
问题内容: 我正在编写一个函数,该函数最多可以调用5000次。当然,我得到了。有什么办法可以以一种非常简单的方式重写此代码?: 顺便说一下,我们可以调用这些函数的深度有什么限制? 问题答案: 使用显式的对象堆栈和循环,而不是调用堆栈和递归:
问题内容: 我正在使用mapstruct映射我的实体和dto类…我在mapper类上存在循环问题… 我没有想法该怎么办…这是我的映射器课程 我的实体类… DTO与我的实体类具有相同的属性… 堆栈轨迹 有人可以帮助我确定为什么循环吗? 问题答案: 和之间存在循环依赖关系。您有3种可能性来解决周期: 一个映射器将始终忽略循环字段。我看到您在的清单中。您可以通过在映射器中忽略它们。 您将拥有显式映射,这
问题内容: 我想读取捕获的异常的完整堆栈跟踪。 例如: 我想阅读“ … 23更多”,以了解异常的来源。 问题答案: 答案很简单,这些行已经在stacktrace中了:) 基本上,以下情况正在发生:
问题内容: 在上面的代码中,我有一个简单的类和一个类级别的实例,也有一个具有相同名称的本地实例。运行上面的代码时,出现以下异常: 问题答案: 您的main方法创建一个实例(),该实例导致实例变量()的初始化,并创建另一个实例,依此类推… 您有无限的构造函数调用链,从而导致。 在上面的代码中,我有一个简单的类和一个类级别的实例 您没有课程级别的实例。您有一个实例级别的实例。如果要一个类级别的实例,请