Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
fea9a4fd83 | |||
0d47db9e2b | |||
f38c2a4fc2 | |||
0e3b069051 | |||
fadead208a | |||
02c72d59e6 | |||
aeca93f41d | |||
e4db81206f | |||
34b55506fe | |||
6aab6189bd | |||
53caf6046c | |||
2981b588d7 | |||
ae9ca7d568 | |||
ae2ce60893 | |||
bf8a0cfc8d | |||
09ee7085d1 | |||
0f310aa450 | |||
c6c9d6dea9 | |||
836134f9fc | |||
8275ff0d22 | |||
2f45a8aad6 | |||
10722b6549 | |||
b9b6e3db16 | |||
57a7aa4410 | |||
f2b4785e33 |
@ -34,6 +34,6 @@ jobs:
|
||||
- name: Upload static files
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "hakurei.app-${{ steps.static-test.outputs.rev }}"
|
||||
name: "hakurei-static-${{ steps.static-test.outputs.rev }}"
|
||||
path: result/*
|
||||
retention-days: 1
|
||||
|
@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
status=0
|
||||
replicas=({1..3}.grapheneos.org)
|
||||
|
||||
for replica in ${replicas[@]}; do
|
||||
echo
|
||||
echo Deploying to $replica
|
||||
echo
|
||||
|
||||
rsync -rpcvl --delete --fsync --preallocate /etc/letsencrypt/ $replica:/etc/letsencrypt &&
|
||||
ssh root@$replica nginx -s reload ||
|
||||
status=1
|
||||
done
|
||||
|
||||
exit $status
|
@ -1,64 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit -o nounset -o pipefail
|
||||
shopt -s extglob
|
||||
|
||||
touch lock
|
||||
exec {fd}< lock
|
||||
if ! flock -n $fd; then
|
||||
echo already processing/deploying static files >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
./process-static $fd
|
||||
|
||||
servers=({0..3}.grapheneos.org)
|
||||
|
||||
rsync -pcv --chmod=F755 --fsync --preallocate certbot-replicate root@${servers[0]}:/usr/local/bin/
|
||||
rsync -pcv --chmod=F644 --fsync --preallocate replicate.conf root@${servers[0]}:/etc/systemd/system/certbot-renew.service.d/
|
||||
|
||||
# use last modified timestamps from 0.grapheneos.org
|
||||
rsync -rptcv --chmod=D755,F644 --delete --fsync --preallocate root@${servers[0]}:/srv/grapheneos.org/ static-production
|
||||
rsync -pcv --chmod=D755,F644 --fsync --preallocate static-production/sitemap.xml{,.gz,.br} static-tmp/
|
||||
rsync -rpcv --chmod=D755,F644 --delete --fsync --preallocate static-tmp/ static-production
|
||||
for f in static-production/**.*(br|gz); do
|
||||
touch -r "${f%.*}" "$f"
|
||||
done
|
||||
changed="$(./generate-sitemap)"
|
||||
xmllint --noblanks static-tmp/sitemap.xml --output static-tmp/sitemap.xml
|
||||
brotli -f static-tmp/sitemap.xml
|
||||
zopfli static-tmp/sitemap.xml
|
||||
rsync -pcv --chmod=D755,F644 --fsync --preallocate static-tmp/sitemap.xml{,.gz,.br} static-production/
|
||||
|
||||
for server in ${servers[@]}; do
|
||||
echo $server
|
||||
|
||||
remote=root@$server
|
||||
active=$(ssh $remote readlink /srv/grapheneos.org)
|
||||
|
||||
if [[ $active = /srv/grapheneos.org_a ]]; then
|
||||
target=/srv/grapheneos.org_b
|
||||
else
|
||||
target=/srv/grapheneos.org_a
|
||||
fi
|
||||
|
||||
echo active is $active
|
||||
echo target is $target
|
||||
echo
|
||||
|
||||
ssh $remote "rm -rf $target && cp -a $active $target"
|
||||
rsync -rptcv --chmod=D755,F644 --delete --fsync --preallocate static-production/ $remote:$target
|
||||
ssh $remote "ln -snf $target /srv/grapheneos.org && sync /srv/grapheneos.org"
|
||||
|
||||
echo "root $target;" > nginx-tmp/root_grapheneos.org.conf
|
||||
rsync -rpcv --chmod=D755,F644 --delete --fsync --preallocate nginx-tmp/{nginx.conf,mime.types,root_grapheneos.org.conf,snippets} $remote:/etc/nginx/
|
||||
ssh $remote nginx -s reload
|
||||
|
||||
echo
|
||||
echo active is now $target
|
||||
echo
|
||||
done
|
||||
|
||||
if [[ -n "$changed" ]]; then
|
||||
./indexnow <<< "$changed"
|
||||
fi
|
@ -1,19 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
generate() {
|
||||
echo $1
|
||||
qrencode -s 1 -o $1 $2
|
||||
gm identify -format '%w×%h\n' $1
|
||||
zopflipng -ym $1 $1
|
||||
}
|
||||
|
||||
generate static/donate-bitcoin.png 'bitcoin:bc1q9qw3g8tdxf3dugkv2z8cahd3axehph0mhsqk96?label=GrapheneOS%20Foundation&message=Donation%20to%20GrapheneOS%20Foundation'
|
||||
generate static/donate-bitcoin-taproot.png 'bitcoin:bc1prqf5hks5dnd4j87wxw3djn20559yhj7wvvcv6fqxpwlg96udkzgqtamhry?label=GrapheneOS%20Foundation&message=Donation%20to%20GrapheneOS%20Foundation'
|
||||
generate static/donate-bitcoin-bip47.png 'bitcoin:PM8TJKmhJNQX6UTFagyuBk8UGmwKM6yDovEokpHBscPgP3Ac7WdK5zaQKh5XLSawyxiGYZS2a7HkAoeL6oHg7Ahn1VXX888yRG4PwF1dojouPtW7tEHT'
|
||||
generate static/donate-monero.png 'monero:862CebHaBpFPgYoNC6zw4U8rsXrDjD8s5LMJNS7yVCRHMUKr9dDi7adMSLUMjkDYJ85xahQTCJHHyK5RCvvRJu9x7iSzN9D?recipient_name=GrapheneOS&tx_description=Donation%20to%20GrapheneOS'
|
||||
generate static/donate-zcash-transparent.png 'zcash:t1SJABjX8rqgzqgrzLW5dUw7ikSDZ2snD8A?label=GrapheneOS%20Foundation&message=Donation%20to%20GrapheneOS%20Foundation'
|
||||
generate static/donate-ethereum.png 'ethereum:0xC822A62E5Ab443E0001f30cEB9B2336D0524fC61'
|
||||
generate static/donate-cardano.png 'web+cardano:addr1q9v89vfwyfssveug5zf2w7leafz8ethq490gvq0ghag883atfnucytpnq2t38dj7cnyngs6ne05cdwu9gseevgmt3ggq2a2wt6'
|
||||
generate static/donate-litecoin.png 'litecoin:ltc1qzssmqueth6zjzr95rkluy5xdx9q4lk8vyrvea9?label=GrapheneOS%20Foundation&message=Donation%20to%20GrapheneOS%20Foundation'
|
@ -2,35 +2,16 @@ from datetime import datetime, timezone
|
||||
from os.path import getmtime
|
||||
from pathlib import Path
|
||||
|
||||
base = "https://grapheneos.org"
|
||||
base = "https://hakurei.app"
|
||||
|
||||
pages = [
|
||||
["/", 0.5],
|
||||
["/.well-known/security.txt", 0.0],
|
||||
["/LICENSE.txt", 0.0],
|
||||
["/articles/", 0.5],
|
||||
["/articles/attestation-compatibility-guide", 0.5],
|
||||
["/articles/grapheneos-servers", 0.1],
|
||||
["/articles/positon-location-service", 0.5],
|
||||
["/articles/server-traffic-shaping", 0.5],
|
||||
["/articles/sitewide-advertising-industry-opt-out", 0.5],
|
||||
["/build", 0.5],
|
||||
["/camera-privacy-policy", 0.0],
|
||||
["/contact", 0.5],
|
||||
["/donate", 0.5],
|
||||
["/faq", 1.0],
|
||||
["/features", 1.0],
|
||||
["/history/", 0.3],
|
||||
["/history/copperheados", 0.1],
|
||||
["/history/legacy-changelog", 0.1],
|
||||
["/hiring", 0.2],
|
||||
#["/faq", 1.0],
|
||||
["/package", 1.0],
|
||||
["/humans.txt", 0.0],
|
||||
["/pdfviewer-privacy-policy", 0.0],
|
||||
["/install/", 0.5],
|
||||
["/install/cli", 0.5],
|
||||
["/install/web", 0.5],
|
||||
["/source", 0.5],
|
||||
["/usage", 1.0]
|
||||
["/install", 0.5],
|
||||
]
|
||||
|
||||
base_mtime = getmtime("static-tmp")
|
||||
@ -38,12 +19,13 @@ entries = []
|
||||
|
||||
for page in pages:
|
||||
path = page[0]
|
||||
if path[-1] != '/' and "." not in path:
|
||||
path += ".html"
|
||||
|
||||
loc = base + path
|
||||
filepath = "static-production" + path
|
||||
if path[-1] == '/':
|
||||
filepath += "index.html"
|
||||
elif "." not in path:
|
||||
filepath += ".html"
|
||||
|
||||
mtime = getmtime(filepath)
|
||||
if mtime > base_mtime:
|
||||
|
4
indexnow → indexnow.py
Executable file → Normal file
@ -1,5 +1,3 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
|
||||
import requests
|
||||
@ -17,7 +15,7 @@ for url in urls:
|
||||
if not validators.url(url):
|
||||
sys.exit(3)
|
||||
|
||||
host = "grapheneos.org"
|
||||
host = "hakurei.app"
|
||||
api_url = "https://api.indexnow.org/indexnow"
|
||||
|
||||
with open("indexnow-key.txt") as keyfile:
|
@ -17,7 +17,7 @@
|
||||
}:
|
||||
stdenvNoCC.mkDerivation rec {
|
||||
pname = "hakurei.app";
|
||||
version = "0.0.0";
|
||||
version = "0.1.0";
|
||||
|
||||
src = ./.;
|
||||
|
||||
@ -89,8 +89,8 @@ stdenvNoCC.mkDerivation rec {
|
||||
xmllint --noblanks static-tmp/sitemap.xml --output static-tmp/sitemap.xml
|
||||
brotli -f static-tmp/sitemap.xml
|
||||
zopfli static-tmp/sitemap.xml
|
||||
rsync -pcv --chmod=D755,F644 --fsync --preallocate static-tmp/sitemap.xml{,.gz,.br} $out
|
||||
rsync -rptcv --chmod=D755,F644 --delete --fsync --preallocate static-production/ $out
|
||||
rsync -pcv --chmod=D755,F644 --fsync --preallocate static-tmp/sitemap.xml{,.gz,.br} $out
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
@ -57,7 +57,7 @@ java -jar node_modules/vnu-jar/build/dist/vnu.jar --Werror --css static-tmp/**/*
|
||||
java -jar node_modules/vnu-jar/build/dist/vnu.jar --Werror --svg static-tmp/**/!(bimi).svg
|
||||
find static-tmp -name '*.html' -exec html-minifier-terser --collapse-whitespace \
|
||||
--process-scripts "application/ld+json" --collapse-boolean-attributes \
|
||||
--remove-attribute-quotes --remove-comments --remove-empty-attributes \
|
||||
--remove-comments --remove-empty-attributes \
|
||||
--remove-redundant-attributes --remove-script-type-attributes \
|
||||
--remove-style-link-type-attributes --sort-attributes --sort-class-name {} -o {} \;
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
{"m.homeserver":{"base_url":"https://matrix.grapheneos.org"}}
|
@ -1 +0,0 @@
|
||||
{"m.server":"matrix.grapheneos.org:443"}
|
@ -1,24 +0,0 @@
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA256
|
||||
|
||||
Contact: mailto:security@grapheneos.org
|
||||
Canonical: https://grapheneos.org/.well-known/security.txt
|
||||
Encryption: data:application/x-age-public-key,age1dcftzgq00ykgwvxl5te6d5clqgx75h2g54c0u8gjc43mcnea7p7q3ma0yx
|
||||
Expires: 2026-03-01T00:00:00Z
|
||||
Preferred-Languages: en
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAEBCAAdFiEEZe7+AiEI4rcIy/z3+ecS5Zr18ioFAmfDGl4ACgkQ+ecS5Zr1
|
||||
8iquHQ//e/Wy0rv3YlGTzzE1bM+h45JKyd+vxYdRmUVM4ic0rLpx+v1vQdIDKUtZ
|
||||
Bax7wE1dMRu02Tpo8vxoEB5QgilxgLtZIi0y3K68/lQJM1BIl20ieL0YfeB9YZt7
|
||||
TZeAbuIMaq0YyzxexTE2GKQQI4qKAIJpMvEnvxmZ2c9dmOiP6T6TYVsYBmiSe7op
|
||||
YUQZ1j6yElVXiBA9FJg1vpaWqPFeSEmi8X0c0ef5tdNKCai1c2/arhELK4msB3ih
|
||||
0Wd7MIukudGvH7Xjfb+H8EZ53OTg/3pAhNdf5E7apwlgNPdp/XPK3Uen+8o0wV4r
|
||||
cQRNBD0gGA8kyEtYfcgndFo5kVkptOZB4OLx7A9wxjDsfMYduknuTGyniZH2DBlH
|
||||
S/H0aWaoLSO2FCFT7OIkXxYTjXdbKZwgtPf5ba6gCpDL/aXrjIPeqHtmo/l2ruhx
|
||||
sc6TYiSHBQuFqQg+X2/49GxDap6k13an5ZiRPUw5CoJl3r3Ztg6ZKu4EiFmLjJ5K
|
||||
AliaN0hjwqxH0AbMc95DLUZ1oRNpk17dlcXl/Fgk7ZI/6GWEqOhEkzf3je9GrZJR
|
||||
53OTDvcarq+rS8kcZ/bSxoBLaZNcNes3kcinaCnGCTjFPgoy2f6CtuuA37KwMc0V
|
||||
TMGaKqRMUCj+lJtdM2HuY0FvWMWjrDKdPrprUx8/umrAa0XPX2k=
|
||||
=WcPV
|
||||
-----END PGP SIGNATURE-----
|
@ -2,22 +2,20 @@
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Page not found | GrapheneOS</title>
|
||||
<title>Page not found | Hakurei</title>
|
||||
<meta name="description" content="The requested page does not exist."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="Page not found"/>
|
||||
<meta property="og:description" content="The requested page does not exist."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image" content="https://hakurei.app/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:image:alt" content="Hakurei logo"/>
|
||||
<meta property="og:site_name" content="Hakurei"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
@ -25,7 +23,8 @@
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
<link rel="me" href="https://port.mk/@hakurei"/>
|
||||
[[js|/js/oneko.js]]
|
||||
</head>
|
||||
<body>
|
||||
{% include "header.html" %}
|
||||
@ -33,7 +32,7 @@
|
||||
<h1><a href="#page-not-found">Page not found</a></h1>
|
||||
|
||||
<p>The requested page does not exist. If you think this is a mistake, please
|
||||
<a href="https://github.com/GrapheneOS/grapheneos.org/issues">report an issue</a>.</p>
|
||||
<a href="https://git.gensokyo.uk/security/hakurei.app/issues">report an issue</a>.</p>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
|
@ -1 +0,0 @@
|
||||
contact@grapheneos.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIUg/m5CoP83b0rfSCzYSVA4cw4ir49io5GPoxbgxdJE
|
@ -1,16 +0,0 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAABCAAdFiEEZe7+AiEI4rcIy/z3+ecS5Zr18ioFAmXMmicACgkQ+ecS5Zr1
|
||||
8iqOKw//WB9N2C+jT/WmMT4t0+aE/0uHvBqoU9KQFmzFWlixibqF70C3gcBkeZK9
|
||||
tvWViI1UhQJktM0A4rwTn3r7T+MvIbwlOzHBKmoWyU2+PSwO3lIO9xbHSvu4/rbp
|
||||
IVkIimgwi9WTvlDvXRhYdXtfJJyXl+qlfbk5sHCOavuR+/xPx3IUDpEZwPvi33VF
|
||||
Z1Sl/3yJztLB96ngmhs29WBniTvxa3owYwjMhHNuTnxNf2m8bIavYA2Vraj9gE8O
|
||||
eTNE5oXkGdv2YJnKW0gbMDV2/F7WBW2/kPZ6yvUxR9texHsFn1dofvf604W09PKP
|
||||
QaIzCKGsJSAVKx/g9mSXm2Z/+hsXLWlJAVK0hmCEhn+Tnmff5KMG7R1WUes0R0rv
|
||||
PK6sa0NbvRRNiwxM08PnZ14WrYBggOZdRBlseqHIdwu2UD2X2vTNK4VOhBbaQPYd
|
||||
EwdIwZxqu0bpUtPIowJqppd/ZWxKOJ4OMcDF/2ENBTqp20RWQnTM1WEV1OoUQeh1
|
||||
XfZDNFBRW7CP4zsbFTIK4DEobxbVXCEVtUK4rGRChX3WL8qhVCgxFf4W8Cwjco2y
|
||||
u40luFdoNyrd2yTVevcX0w2W/4JvJ5reikepYOAbCwbLbWNJnKoRA+0ZgZ0IE1B4
|
||||
+RDmB5iIefAPjpD/Do/TtlFjRcyh6g4kNWnS1fTzB9jGNP/PQWs=
|
||||
=rnsE
|
||||
-----END PGP SIGNATURE-----
|
@ -1,2 +0,0 @@
|
||||
untrusted comment: verify with factory.pub
|
||||
RWQZW9NItOuQYMZY8ZMX9VX4hfy54df7Pt3Yh1qEWTyRlQKH4PdteqeKUk9jljywlcCl8nzKJAj75F70Y5FTsAK4cw2aV+CZcAA=
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 7.1 KiB |
@ -1,176 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Attestation compatibility guide | Articles | GrapheneOS</title>
|
||||
<meta name="description" content="Guide on using remote attestation in a way that's compatible with GrapheneOS."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="GrapheneOS attestation compatibility guide"/>
|
||||
<meta property="og:description" content="Guide on using remote attestation in a way that's compatible with GrapheneOS."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/articles/attestation-compatibility-guide"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/articles/attestation-compatibility-guide"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
</head>
|
||||
<body>
|
||||
{% include "header.html" %}
|
||||
<main id="attestation-compatibility-guide">
|
||||
<h1><a href="#attestation-compatibility-guide">Attestation compatibility guide</a></h1>
|
||||
|
||||
<p>Apps using the Play Integrity API or
|
||||
<a href="https://developer.android.com/training/safetynet/deprecation-timeline">obsolete</a>
|
||||
SafetyNet Attestation API to check the authenticity/integrity of the OS can support
|
||||
GrapheneOS by using the standard Android hardware attestation API instead and
|
||||
permitting our official release signing keys. Android's
|
||||
<a href="https://developer.android.com/training/articles/security-key-attestation">hardware
|
||||
attestation API</a> provides a much stronger form of attestation than the Play
|
||||
Integrity API with the ability to whitelist the keys of alternate operating systems.
|
||||
It also avoids an unnecessary dependency on Google Play services and Google's
|
||||
Play Integrity servers.</p>
|
||||
|
||||
<p>The standard hardware attestation API can be used to verify the authenticity/integrity
|
||||
of the hardware, firmware, OS and the app running on it. It provides a verified boot key
|
||||
fingerprint for the OS for permitting secure aftermarket operating systems. The app id,
|
||||
signing key fingerprint(s) and version code of the app enabling hardware attestation are
|
||||
included in the signed public key certificate for the generated key. This enables the
|
||||
app's service to make sure the app is genuine and unmodified along with chaining trust
|
||||
through the OS to the app which can sign messages with the attested hardware keystore
|
||||
key to prove they come from their app running on top of a verified OS, firmware and
|
||||
hardware. The only practical way to bypass hardware attestation is through exploiting
|
||||
the hardware keystore to obtain attestation signing keys, which is protected against by
|
||||
the ability to revoke keys that are being misused. Play Integrity API strong integrity
|
||||
level is directly based on the hardware key attestation API, but apps using it directly
|
||||
can support aftermarket operating systems, check the hardware attested OS patch level
|
||||
and other provided information. The hardware attestation API also supports pinning-based
|
||||
security instead of only root-based security where keys can be leaked and used to fake
|
||||
attestations. Apps can use pinning to establish a much higher security pairing with a
|
||||
specific device to obtain fresh attestations with a very high level security based on
|
||||
the security of the device's own hardware keystore rather than the overall ecosystem.
|
||||
Hardware attestation also doesn't require using any Google service beyond regularly
|
||||
fetching the list of revoked keys for root-based attestation. The app's service doesn't
|
||||
have to go down or start permitting anything if the Google services becomes unavailable
|
||||
or blocks the app from using it for one reason or another. Using hardware attestation is
|
||||
therefore more reliable and lower risk for apps.</p>
|
||||
|
||||
<p>Devices have been required to ship with hardware attestation support since Android
|
||||
8. You can use hardware attestation on devices running Android 8 or later when the
|
||||
<code>ro.product.first_api_level</code> system property isn't set to 25 or below,
|
||||
which indicates they launched with Android 8 or later with hardware attestation
|
||||
support as a mandatory feature. On older devices, you can continue using the Play
|
||||
Integrity API. Some low quality devices shipped broken implementations of hardware
|
||||
attestation despite the requirement to have it working for CDD/CTS certification and
|
||||
the Play Integrity API currently still passes on those devices wrongly claiming them
|
||||
to be CTS certified. If you don't want to fail on those devices, then you can start
|
||||
with hardware attestation and fall back to the Play Integrity API or do both and
|
||||
accept either passing as success.</p>
|
||||
|
||||
<p>Google provides a <a href="https://github.com/google/android-key-attestation">key
|
||||
attestation library</a> with examples. Our <a href="https://github.com/GrapheneOS/Auditor">MIT
|
||||
/ Apache 2 licensed Auditor app</a> can be used as a reference implementation for
|
||||
verifying hardware-based attestations. There are some subtleties in the verification
|
||||
process such as making sure only the 2nd certificate in the chain (the one signing the
|
||||
certificate for the key generated by your app) has an attestation extension to prevent
|
||||
making a fake attestation by extending the chain. You can reuse our code and simply
|
||||
omit support for an app generated attestation signing key (attest key) and the other
|
||||
pinning support.</p>
|
||||
|
||||
<p>After verifying the signature of the attestation certificate chain and extracting
|
||||
the attestation metadata, you can enforce that <code>verifiedBootState</code> is
|
||||
either <code>Verified</code> or <code>SelfSigned</code>. For the
|
||||
<code>SelfSigned</code> case, you can check that <code>verifiedBootKey</code> matches
|
||||
one of the official GrapheneOS verified boot keys. These are the base16-encoded
|
||||
verified boot key fingerprints for the official GrapheneOS releases:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>0508de44ee00bfb49ece32c418af1896391abde0f05b64f41bc9a2dfb589445b</code>: Pixel 9a</li>
|
||||
<li><code>af4d2c6e62be0fec54f0271b9776ff061dd8392d9f51cf6ab1551d346679e24c</code>: Pixel 9 Pro Fold</li>
|
||||
<li><code>55d3c2323db91bb91f20d38d015e85112d038f6b6b5738fe352c1a80dba57023</code>: Pixel 9 Pro XL</li>
|
||||
<li><code>f729cab861da1b83fdfab402fc9480758f2ae78ee0b61c1f2137dd1ab7076e86</code>: Pixel 9 Pro</li>
|
||||
<li><code>9e6a8f3e0d761a780179f93acd5721ba1ab7c8c537c7761073c0a754b0e932de</code>: Pixel 9</li>
|
||||
<li><code>096b8bd6d44527a24ac1564b308839f67e78202185cbff9cfdcb10e63250bc5e</code>: Pixel 8a</li>
|
||||
<li><code>896db2d09d84e1d6bb747002b8a114950b946e5825772a9d48ba7eb01d118c1c</code>: Pixel 8 Pro</li>
|
||||
<li><code>cd7479653aa88208f9f03034810ef9b7b0af8a9d41e2000e458ac403a2acb233</code>: Pixel 8</li>
|
||||
<li><code>ee0c9dfef6f55a878538b0dbf7e78e3bc3f1a13c8c44839b095fe26dd5fe2842</code>: Pixel Fold</li>
|
||||
<li><code>94df136e6c6aa08dc26580af46f36419b5f9baf46039db076f5295b91aaff230</code>: Pixel Tablet</li>
|
||||
<li><code>508d75dea10c5cbc3e7632260fc0b59f6055a8a49dd84e693b6d8899edbb01e4</code>: Pixel 7a</li>
|
||||
<li><code>bc1c0dd95664604382bb888412026422742eb333071ea0b2d19036217d49182f</code>: Pixel 7 Pro</li>
|
||||
<li><code>3efe5392be3ac38afb894d13de639e521675e62571a8a9b3ef9fc8c44fd17fa1</code>: Pixel 7</li>
|
||||
<li><code>08c860350a9600692d10c8512f7b8e80707757468e8fbfeea2a870c0a83d6031</code>: Pixel 6a</li>
|
||||
<li><code>439b76524d94c40652ce1bf0d8243773c634d2f99ba3160d8d02aa5e29ff925c</code>: Pixel 6 Pro</li>
|
||||
<li><code>f0a890375d1405e62ebfd87e8d3f475f948ef031bbf9ddd516d5f600a23677e8</code>: Pixel 6</li>
|
||||
</ul>
|
||||
|
||||
<p>The <code>verifiedBootKey</code> field is binary data so you either need to encode
|
||||
it as base16 to compare with these or convert these to binary. An easy approach is
|
||||
storing the permitted key fingerprints in a set and enforcing that the verified boot
|
||||
key is in the permitted set when <code>verifiedBootState</code> is
|
||||
<code>SelfSigned</code>.</p>
|
||||
|
||||
<p>GrapheneOS regularly adds support for new devices so you should have a process for
|
||||
regularly adding the new verified boot key fingerprints from this page.</p>
|
||||
|
||||
<p>The hardware attestation API also provides other useful information signed by the
|
||||
hardware including the OS patch level, in a way that even an attacker exploiting the
|
||||
OS after boot to gain root cannot trivially bypass. It's a better feature than the
|
||||
Play Integrity API which has to be designed for the lowest common denominator.</p>
|
||||
|
||||
<p>GrapheneOS users are strongly encouraged to share this documentation with app
|
||||
developers enforcing only being able to use the stock OS. Send an email to the
|
||||
developers and leave a review of the app with a link to this information. Share it
|
||||
with other users and create pressure to support GrapheneOS rather than locking users
|
||||
into the stock OS without a valid security reason. GrapheneOS not only upholds the
|
||||
app security model but substantially reinforces it, so it cannot be justified with
|
||||
reasoning based on security, anti-fraud, etc.</p>
|
||||
|
||||
<article id="apps-banning-grapheneos">
|
||||
<h2><a href="#apps-banning-grapheneos">Apps banning GrapheneOS</a></h2>
|
||||
|
||||
<p>This is a list of the apps banning GrapheneOS with the Play Integrity API with
|
||||
links to their Play Store pages for leaving feedback:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://play.google.com/store/apps/details?id=au.gov.mygov.mygovapp" rel="nofollow">myGov</a> (Australian government app)</li>
|
||||
<li><a href="https://play.google.com/store/apps/details?id=br.gov.meugovbr" rel="nofollow">gov.br</a> (Brazilian government app)</li>
|
||||
<li><a href="https://play.google.com/store/apps/details?id=ch.ticketcorner.mobile.app.Android" rel="nofollow">Ticketcorner</a></li>
|
||||
<li><a href="https://play.google.com/store/apps/details?id=com.authy.authy" rel="nofollow">Authy</a></li>
|
||||
<li><a href="https://play.google.com/store/apps/details?id=com.ebay.mobile" rel="nofollow">eBay</a></li>
|
||||
<li><a href="https://play.google.com/store/apps/details?id=com.mcdonalds.mobileapp" rel="nofollow">McDonald's</a> (International app used for many but not all countries not including the US)</li>
|
||||
<li><a href="https://play.google.com/store/apps/details?id=com.ridedott.rider" rel="nofollow">Dott</a></li>
|
||||
<li><a href="https://play.google.com/store/apps/details?id=com.swissquote.android" rel="nofollow">Swissquote</a></li>
|
||||
<li><a href="https://play.google.com/store/apps/details?id=com.swisssign.swissid.mobile" rel="nofollow">SwissID</a></li>
|
||||
<li><a href="https://play.google.com/store/apps/details?id=de.tk.tkapp" rel="nofollow">TK-App</a> (German health insurance app which uses it for fingerprint login)</li>
|
||||
<li><a href="https://play.google.com/store/apps/details?id=it.pagopa.io.app" rel="nofollow">IO</a> (Italian government app which uses it for the digital wallet feature)</li>
|
||||
</ul>
|
||||
|
||||
<p>In addition to leaving feedback for these apps on the Play Store, file support
|
||||
requests and leave feedback on third party review sites. Ask them to stop banning
|
||||
GrapheneOS and explain that it's a much more secure OS than what they permit which
|
||||
does not lose any of the standard security model. Explain that they can use the
|
||||
hardware key attestation API to verify that a device is running GrapheneOS to permit
|
||||
it alongside an OS licensing Google apps as they do with the Play Integrity API
|
||||
already. Make sure to push back against false claims that it has something to do
|
||||
with compatibility or security issues. The only reason they aren't permitting it is
|
||||
because we do not license Google Mobile Services (GMS) and these apps are enforcing
|
||||
Google's business interests rather than security.</p>
|
||||
</article>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
@ -1,726 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>GrapheneOS servers | Articles | GrapheneOS</title>
|
||||
<meta name="description" content="Documentation on GrapheneOS servers."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="GrapheneOS servers"/>
|
||||
<meta property="og:description" content="Documentation on GrapheneOS servers."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/articles/grapheneos-servers"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/articles/grapheneos-servers"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
[[js|/js/redirect.js]]
|
||||
</head>
|
||||
<body>
|
||||
{% include "header.html" %}
|
||||
<main id="grapheneos-servers">
|
||||
<h1><a href="#grapheneos-servers">GrapheneOS servers</a></h1>
|
||||
|
||||
<p>This is a detailed list of the public GrapheneOS servers.</p>
|
||||
|
||||
<p>We use hardened local machines for building and signing rather than servers outside
|
||||
our physical control, so information on that infrastructure is outside the scope of this
|
||||
page but may be provided in the future elsewhere.</p>
|
||||
|
||||
<nav id="table-of-contents">
|
||||
<h2><a href="#table-of-contents">Table of contents</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#grapheneos.org">GrapheneOS website</a></li>
|
||||
<li><a href="#staging.grapheneos.org">Staging GrapheneOS website</a></li>
|
||||
<li><a href="#releases.grapheneos.org">GrapheneOS release servers</a></li>
|
||||
<li><a href="#grapheneos.network">GrapheneOS network servers</a></li>
|
||||
<li><a href="#mail.grapheneos.org">GrapheneOS mail server</a></li>
|
||||
<li><a href="#discuss.grapheneos.org">GrapheneOS discussion forum server</a></li>
|
||||
<li><a href="#grapheneos.social">GrapheneOS Mastodon server</a></li>
|
||||
<li><a href="#matrix.grapheneos.org">GrapheneOS Matrix server</a></li>
|
||||
<li><a href="#ns1.grapheneos.org">GrapheneOS DNS servers</a></li>
|
||||
<li><a href="#ns1.staging.grapheneos.org">Staging GrapheneOS DNS server</a></li>
|
||||
<li><a href="#attestation.app">Attestation website and service</a></li>
|
||||
<li><a href="#staging.attestation.app">Staging attestation website and service</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<section id="grapheneos.org">
|
||||
<h2><a href="#grapheneos.org">GrapheneOS website</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/grapheneos.org">Repository</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/grapheneos.org/issues">Issue tracker</a></li>
|
||||
</ul>
|
||||
|
||||
<p>Specs:</p>
|
||||
|
||||
<ul>
|
||||
<li>3x OVH VPS vps2023-le-2</li>
|
||||
<li>2 core</li>
|
||||
<li>2 GB memory</li>
|
||||
<li>40 GB NVMe SSD storage</li>
|
||||
<li>500 Mbit/s bandwidth</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>1x BuyVM Slice 1024</li>
|
||||
<li>1 core</li>
|
||||
<li>1 GB memory</li>
|
||||
<li>20 GB NVMe SSD storage</li>
|
||||
<li>1000 Mbit/s bandwidth</li>
|
||||
</ul>
|
||||
|
||||
<p>Domains:</p>
|
||||
|
||||
<ul>
|
||||
<li>grapheneos.org</li>
|
||||
<li>www.grapheneos.org</li>
|
||||
<li>grapheneos.app</li>
|
||||
<li>www.grapheneos.app</li>
|
||||
<li>grapheneos.ca</li>
|
||||
<li>www.grapheneos.ca</li>
|
||||
<li>grapheneos.com</li>
|
||||
<li>www.grapheneos.com</li>
|
||||
<li>grapheneos.dev</li>
|
||||
<li>www.grapheneos.dev</li>
|
||||
<li>grapheneos.foundation</li>
|
||||
<li>www.grapheneos.foundation</li>
|
||||
<li>grapheneos.info</li>
|
||||
<li>www.grapheneos.info</li>
|
||||
<li>grapheneos.net</li>
|
||||
<li>www.grapheneos.net</li>
|
||||
<li>grapheneos.ovh</li>
|
||||
<li>www.grapheneos.ovh</li>
|
||||
<li>grapheneos.page</li>
|
||||
<li>www.grapheneos.page</li>
|
||||
<li>vanadium.app</li>
|
||||
<li>www.vanadium.app</li>
|
||||
</ul>
|
||||
|
||||
<p>IPs:</p>
|
||||
|
||||
<ul>
|
||||
<li>51.222.156.101 (0.grapheneos.org) — OVH bhs6</li>
|
||||
<li>2607:5300:205:200::29c6 (0.grapheneos.org) — OVH bhs6</li>
|
||||
<li>209.141.35.164 (1.grapheneos.org) — BuyVM Las Vegas</li>
|
||||
<li>2605:6400:20:1131:8088:e08:84e6:632 (1.grapheneos.org) — BuyVM Las Vegas</li>
|
||||
<li>54.37.41.189 (2.grapheneos.org) — OVH gra8</li>
|
||||
<li>2001:41d0:304:200::b109 (2.grapheneos.org) — OVH gra8</li>
|
||||
<li>51.79.160.50 (3.grapheneos.org) — OVH sgp2</li>
|
||||
<li>2402:1f00:8000:800::16d6 (3.grapheneos.org) — OVH sgp2</li>
|
||||
</ul>
|
||||
|
||||
<p>Ports:</p>
|
||||
|
||||
<ul>
|
||||
<li>TCP 22 ssh</li>
|
||||
<li>TCP 80 http</li>
|
||||
<li>TCP 443 https</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="staging.grapheneos.org">
|
||||
<h2><a href="#staging.grapheneos.org">Staging GrapheneOS website</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/grapheneos.org">Repository</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/grapheneos.org/issues">Issue tracker</a></li>
|
||||
</ul>
|
||||
|
||||
<p>Specs:</p>
|
||||
|
||||
<ul>
|
||||
<li>BuyVM Slice 1024</li>
|
||||
<li>1 core</li>
|
||||
<li>1 GB memory</li>
|
||||
<li>20 GB NVMe SSD storage</li>
|
||||
<li>1000 Mbit/s bandwidth</li>
|
||||
</ul>
|
||||
|
||||
<p>Domains:</p>
|
||||
|
||||
<ul>
|
||||
<li>staging.grapheneos.org</li>
|
||||
</ul>
|
||||
|
||||
<p>IPs:</p>
|
||||
|
||||
<ul>
|
||||
<li>199.195.250.78 — BuyVM New York</li>
|
||||
<li>2605:6400:10:9d6:6d84:e183:acda:16d7 — BuyVM New York</li>
|
||||
</ul>
|
||||
|
||||
<p>Ports:</p>
|
||||
|
||||
<ul>
|
||||
<li>TCP 22 ssh</li>
|
||||
<li>TCP 80 http</li>
|
||||
<li>TCP 443 https</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="releases.grapheneos.org">
|
||||
<h2><a href="#releases.grapheneos.org">GrapheneOS release servers</a></h2>
|
||||
|
||||
<p>These are the static file servers for GrapheneOS releases and our app
|
||||
repository. These are used by the releases page and web installer along with the
|
||||
System Updater and App Store (app repository client) within the OS.</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/releases.grapheneos.org">Repository</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/releases.grapheneos.org/issues">Issue tracker</a></li>
|
||||
</ul>
|
||||
|
||||
<p>Specs:</p>
|
||||
|
||||
<ul>
|
||||
<li>Macarne dedicated server (sponsored by <a href="https://macarne.com/">Macarne</a>)</li>
|
||||
<li>Ryzen 9950X</li>
|
||||
<li>128 GB DDR5</li>
|
||||
<li>2x 2 TB NVMe SSD storage</li>
|
||||
<li>25000 Mbit/s bandwidth</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>2x ReliableSite dedicated server (sponsored by <a href="https://www.reliablesite.net/">ReliableSite</a>)</li>
|
||||
<li>Ryzen 9900X</li>
|
||||
<li>192 GB DDR5</li>
|
||||
<li>2x 4 TB NVMe SSD storage</li>
|
||||
<li>10000 Mbit/s bandwidth</li>
|
||||
</ul>
|
||||
|
||||
<p>Domains:</p>
|
||||
|
||||
<ul>
|
||||
<li>releases.grapheneos.org</li>
|
||||
<li>seamlessupdate.app</li>
|
||||
<li>www.seamlessupdate.app</li>
|
||||
<li>apps.grapheneos.org</li>
|
||||
</ul>
|
||||
|
||||
<p>IPs:</p>
|
||||
|
||||
<ul>
|
||||
<li>45.90.185.33 (4.releases.grapheneos.org) — Macarne Amsterdam</li>
|
||||
<li>2a14:3f87:6920:250::100 (4.releases.grapheneos.org) — Macarne Amsterdam</li>
|
||||
<li>172.96.172.37 (5.releases.grapheneos.org) — ReliableSite Miami</li>
|
||||
<li>2605:9880:400:1100:15:1240:515:6e (5.releases.grapheneos.org) — ReliableSite Miami</li>
|
||||
<li>104.194.8.203 (6.releases.grapheneos.org) — ReliableSite Los Angeles</li>
|
||||
<li>2605:9880:200:20::113 (6.releases.grapheneos.org) — ReliableSite Los Angeles</li>
|
||||
</ul>
|
||||
|
||||
<p>Ports:</p>
|
||||
|
||||
<ul>
|
||||
<li>TCP 22 ssh</li>
|
||||
<li>TCP 80 http</li>
|
||||
<li>TCP 443 https</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="grapheneos.network">
|
||||
<h2><a href="#grapheneos.network">GrapheneOS network servers</a></h2>
|
||||
|
||||
<p>These are the default servers used by GrapheneOS for connectivity checks,
|
||||
secure network time, attestation key provisioning and Predicted Satellite Data
|
||||
Service (PSDS). These either serve empty responses or provide reverse proxies to
|
||||
other services.</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/grapheneos.network">Repository</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/grapheneos.network/issues">Issue tracker</a></li>
|
||||
</ul>
|
||||
|
||||
<p>Specs:</p>
|
||||
|
||||
<ul>
|
||||
<li>3x OVH VPS vps2023-le-2</li>
|
||||
<li>2 core</li>
|
||||
<li>2 GB memory</li>
|
||||
<li>40 GB NVMe SSD storage</li>
|
||||
<li>500 Mbit/s bandwidth</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>1x BuyVM Slice 1024</li>
|
||||
<li>1 core</li>
|
||||
<li>1 GB memory</li>
|
||||
<li>20 GB NVMe SSD storage</li>
|
||||
<li>1000 Mbit/s bandwidth</li>
|
||||
</ul>
|
||||
|
||||
<p>Domains:</p>
|
||||
|
||||
<ul>
|
||||
<li>grapheneos.network - HTTP/HTTPS connectivity checks</li>
|
||||
<li>connectivitycheck.grapheneos.network - HTTP/HTTPS connectivity checks</li>
|
||||
<li>www.grapheneos.network</li>
|
||||
<li>grapheneos.online - HTTP/HTTPS connectivity checks</li>
|
||||
<li>connectivitycheck.grapheneos.online - HTTP/HTTPS connectivity checks</li>
|
||||
<li>www.grapheneos.online</li>
|
||||
<li>broadcom.psds.grapheneos.org - HTTPS Broadcom PSDS data cache</li>
|
||||
<li>samsung.psds.grapheneos.org - HTTPS Samsung PSDS data cache</li>
|
||||
<li>qualcomm.psds.grapheneos.org - HTTPS Qualcomm PSDS data cache</li>
|
||||
<li>remoteprovisioning.grapheneos.org - HTTPS reverse proxy to remoteprovisioning.google.com</li>
|
||||
<li>widevineprovisioning.grapheneos.org - HTTPS reverse proxy for Widevine provisioning</li>
|
||||
<li>time.grapheneos.org - HTTPS time server with millisecond precision X-Time header</li>
|
||||
<li>supl.grapheneos.org - TLS reverse proxy to supl.google.com</li>
|
||||
<li>nominatim.grapheneos.org - HTTPS reverse proxy to nominatim.openstreetmap.org, which will become our own instance of Nominatim instead of a proxy</li>
|
||||
<li>gs-loc.apple.grapheneos.org - HTTPS reverse proxy to Apple's network location service, which will remain an option after we have our own location service</li>
|
||||
<li>update.vanadium.app - HTTPS reverse proxy to update.googleapis.com for Chromium component updates (will be hosted directly in the future)</li>
|
||||
<li>dl.vanadium.app - HTTPS reverse proxy to CDNs for Chromium component updates (will be hosted directly in the future)</li>
|
||||
</ul>
|
||||
|
||||
<p>IPs:</p>
|
||||
|
||||
<ul>
|
||||
<li>51.222.159.116 (0.grapheneos.network) — OVH bhs6</li>
|
||||
<li>2607:5300:205:200::2584 (0.grapheneos.network) — OVH bhs6</li>
|
||||
<li>209.141.37.35 (1.grapheneos.network) — BuyVM Las Vegas</li>
|
||||
<li>2605:6400:20:387:72d4:dab9:a369:f351 (1.grapheneos.network) — BuyVM Las Vegas</li>
|
||||
<li>54.37.41.188 (2.grapheneos.network) — OVH gra8</li>
|
||||
<li>2001:41d0:304:200::902f (2.grapheneos.network) — OVH gra8</li>
|
||||
<li>51.79.161.36 (3.grapheneos.network) — OVH sgp2</li>
|
||||
<li>2402:1f00:8000:800::1949 (3.grapheneos.network) — OVH sgp2</li>
|
||||
</ul>
|
||||
|
||||
<p>Ports:</p>
|
||||
|
||||
<ul>
|
||||
<li>TCP 22 ssh</li>
|
||||
<li>TCP 80 http</li>
|
||||
<li>UDP 123 ntp</li>
|
||||
<li>TCP 443 https</li>
|
||||
<li>TCP 7275 supl</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="mail.grapheneos.org">
|
||||
<h2><a href="#mail.grapheneos.org">GrapheneOS mail server</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/mail.grapheneos.org">Repository</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/mail.grapheneos.org/issues">Issue tracker</a></li>
|
||||
</ul>
|
||||
|
||||
<p>Specs:</p>
|
||||
|
||||
<ul>
|
||||
<li>OVH VPS vps2023-le-2</li>
|
||||
<li>2 core</li>
|
||||
<li>2 GB memory</li>
|
||||
<li>40 GB NVMe SSD storage</li>
|
||||
<li>500 Mbit/s bandwidth</li>
|
||||
</ul>
|
||||
|
||||
<p>Domains:</p>
|
||||
|
||||
<ul>
|
||||
<li>mail.grapheneos.net</li>
|
||||
<li>mail.grapheneos.org</li>
|
||||
<li>mta-sts.attestation.app</li>
|
||||
<li>mta-sts.discuss.grapheneos.org</li>
|
||||
<li>mta-sts.grapheneos.app</li>
|
||||
<li>mta-sts.grapheneos.ca</li>
|
||||
<li>mta-sts.grapheneos.com</li>
|
||||
<li>mta-sts.grapheneos.dev</li>
|
||||
<li>mta-sts.grapheneos.foundation</li>
|
||||
<li>mta-sts.grapheneos.info</li>
|
||||
<li>mta-sts.grapheneos.net</li>
|
||||
<li>mta-sts.grapheneos.network</li>
|
||||
<li>mta-sts.grapheneos.online</li>
|
||||
<li>mta-sts.grapheneos.org</li>
|
||||
<li>mta-sts.grapheneos.ovh</li>
|
||||
<li>mta-sts.grapheneos.page</li>
|
||||
<li>mta-sts.grapheneos.social</li>
|
||||
<li>mta-sts.mail.grapheneos.org</li>
|
||||
<li>mta-sts.matrix.grapheneos.org</li>
|
||||
<li>mta-sts.seamlessupdate.app</li>
|
||||
<li>mta-sts.vanadium.app</li>
|
||||
</ul>
|
||||
|
||||
<p>IPs:</p>
|
||||
|
||||
<ul>
|
||||
<li>192.99.98.22 — OVH bhs6</li>
|
||||
<li>2607:5300:205:200::472f — OVH bhs6</li>
|
||||
</ul>
|
||||
|
||||
<p>Ports:</p>
|
||||
|
||||
<ul>
|
||||
<li>TCP 22 ssh</li>
|
||||
<li>TCP 25 smtp</li>
|
||||
<li>TCP 80 http</li>
|
||||
<li>TCP 443 https</li>
|
||||
<li>TCP 465 submissions</li>
|
||||
<li>TCP 993 imaps</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="discuss.grapheneos.org">
|
||||
<h2><a href="#discuss.grapheneos.org">GrapheneOS discussion forum server</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/discuss.grapheneos.org">Repository</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/discuss.grapheneos.org/issues">Issue tracker</a></li>
|
||||
</ul>
|
||||
|
||||
<p>Specs:</p>
|
||||
|
||||
<ul>
|
||||
<li>OVH VPS vps2023-le-4</li>
|
||||
<li>4 core</li>
|
||||
<li>4 GB memory</li>
|
||||
<li>80 GB NVMe SSD storage</li>
|
||||
<li>1000 Mbit/s bandwidth</li>
|
||||
</ul>
|
||||
|
||||
<p>Domains:</p>
|
||||
|
||||
<ul>
|
||||
<li>discuss.grapheneos.org</li>
|
||||
</ul>
|
||||
|
||||
<p>IPs:</p>
|
||||
|
||||
<ul>
|
||||
<li>51.222.14.6 — OVH bhs6</li>
|
||||
<li>2607:5300:205:200::29e8 — OVH bhs6</li>
|
||||
</ul>
|
||||
|
||||
<p>Ports:</p>
|
||||
|
||||
<ul>
|
||||
<li>TCP 22 ssh</li>
|
||||
<li>TCP 80 http</li>
|
||||
<li>TCP 443 https</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="grapheneos.social">
|
||||
<h2><a href="#grapheneos.social">GrapheneOS Mastodon server</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/grapheneos.social">Repository</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/grapheneos.social/issues">Issue tracker</a></li>
|
||||
</ul>
|
||||
|
||||
<p>Specs:</p>
|
||||
|
||||
<ul>
|
||||
<li>OVH VPS vps2023-le-4</li>
|
||||
<li>4 core</li>
|
||||
<li>4 GB memory</li>
|
||||
<li>80 GB NVMe SSD storage</li>
|
||||
<li>1000 Mbit/s bandwidth</li>
|
||||
</ul>
|
||||
|
||||
<p>Domains:</p>
|
||||
|
||||
<ul>
|
||||
<li>grapheneos.social</li>
|
||||
<li>www.grapheneos.social</li>
|
||||
</ul>
|
||||
|
||||
<p>IPs:</p>
|
||||
|
||||
<ul>
|
||||
<li>51.222.159.14 — OVH bhs6</li>
|
||||
<li>2607:5300:205:200::5e3f — OVH bhs6</li>
|
||||
</ul>
|
||||
|
||||
<p>Ports:</p>
|
||||
|
||||
<ul>
|
||||
<li>TCP 22 ssh</li>
|
||||
<li>TCP 80 http</li>
|
||||
<li>TCP 443 https</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="matrix.grapheneos.org">
|
||||
<h2><a href="#matrix.grapheneos.org">GrapheneOS Matrix server</a></h2>
|
||||
|
||||
<p>This server primarily runs the synapse Matrix server with PostgreSQL behind an
|
||||
nginx web server. It also runs the mjolnir bot for moderation and matterbridge is
|
||||
used to implement a bridge between Matrix, IRC and Telegram.</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/matrix.grapheneos.org">Repository</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/matrix.grapheneos.org/issues">Issue tracker</a></li>
|
||||
</ul>
|
||||
|
||||
<p>Specs:</p>
|
||||
|
||||
<ul>
|
||||
<li>OVH VPS vps2020-comfort-4-8-160</li>
|
||||
<li>4 core</li>
|
||||
<li>8 GB memory</li>
|
||||
<li>160 GB NVMe SSD storage</li>
|
||||
<li>1000 Mbit/s bandwidth</li>
|
||||
</ul>
|
||||
|
||||
<p>Domains:</p>
|
||||
|
||||
<ul>
|
||||
<li>matrix.grapheneos.org</li>
|
||||
<li>element.grapheneos.org</li>
|
||||
</ul>
|
||||
|
||||
<p>IPs:</p>
|
||||
|
||||
<ul>
|
||||
<li>51.79.51.42 — OVH bhs6</li>
|
||||
<li>2607:5300:205:200::26e1 — OVH bhs6</li>
|
||||
</ul>
|
||||
|
||||
<p>Ports:</p>
|
||||
|
||||
<ul>
|
||||
<li>TCP 22 ssh</li>
|
||||
<li>TCP 80 http</li>
|
||||
<li>TCP 443 https</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="ns1.grapheneos.org">
|
||||
<h2><a href="#ns1.grapheneos.org">GrapheneOS DNS servers</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/ns1.grapheneos.org">Repository</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/ns1.grapheneos.org/issues">Issue tracker</a></li>
|
||||
</ul>
|
||||
|
||||
<p>Specs:</p>
|
||||
|
||||
<ul>
|
||||
<li>4x OVH VPS vps2023-le-2</li>
|
||||
<li>2 core</li>
|
||||
<li>2 GB memory</li>
|
||||
<li>40 GB NVMe SSD storage</li>
|
||||
<li>500 Mbit/s bandwidth</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>3x BuyVM Slice 1024</li>
|
||||
<li>1 core</li>
|
||||
<li>1 GB memory</li>
|
||||
<li>20 GB NVMe SSD storage</li>
|
||||
<li>1000 Mbit/s bandwidth</li>
|
||||
</ul>
|
||||
|
||||
<p>Domains:</p>
|
||||
|
||||
<ul>
|
||||
<li>ns1.attestation.app</li>
|
||||
<li>ns1.grapheneos.app</li>
|
||||
<li>ns1.grapheneos.ca</li>
|
||||
<li>ns1.grapheneos.com</li>
|
||||
<li>ns1.grapheneos.dev</li>
|
||||
<li>ns1.grapheneos.foundation</li>
|
||||
<li>ns1.grapheneos.info</li>
|
||||
<li>ns1.grapheneos.net</li>
|
||||
<li>ns1.grapheneos.network</li>
|
||||
<li>ns1.grapheneos.online</li>
|
||||
<li>ns1.grapheneos.org</li>
|
||||
<li>ns1.grapheneos.ovh</li>
|
||||
<li>ns1.grapheneos.page</li>
|
||||
<li>ns1.grapheneos.social</li>
|
||||
<li>ns1.seamlessupdate.app</li>
|
||||
<li>ns1.vanadium.app</li>
|
||||
<li>ns2.attestation.app</li>
|
||||
<li>ns2.grapheneos.app</li>
|
||||
<li>ns2.grapheneos.ca</li>
|
||||
<li>ns2.grapheneos.com</li>
|
||||
<li>ns2.grapheneos.dev</li>
|
||||
<li>ns2.grapheneos.foundation</li>
|
||||
<li>ns2.grapheneos.info</li>
|
||||
<li>ns2.grapheneos.net</li>
|
||||
<li>ns2.grapheneos.network</li>
|
||||
<li>ns2.grapheneos.online</li>
|
||||
<li>ns2.grapheneos.org</li>
|
||||
<li>ns2.grapheneos.ovh</li>
|
||||
<li>ns2.grapheneos.page</li>
|
||||
<li>ns2.grapheneos.social</li>
|
||||
<li>ns2.seamlessupdate.app</li>
|
||||
<li>ns2.vanadium.app</li>
|
||||
</ul>
|
||||
|
||||
<p>IPs:</p>
|
||||
|
||||
<ul>
|
||||
<li>185.187.152.9 (anycast), 51.161.34.158 (0.ns1.grapheneos.org) — OVH bhs6</li>
|
||||
<li>2a05:b0c4:1::8 (anycast), 2607:5300:205:200::eaa (0.ns1.grapheneos.org) — OVH bhs6</li>
|
||||
<li>185.187.152.9 (anycast), 15.204.8.153 (1.ns1.grapheneos.org) — OVH US us-west-or-2</li>
|
||||
<li>2a05:b0c4:1::8 (anycast), 2604:2dc0:202:300::23a6 (1.ns1.grapheneos.org) — OVH us-west-or-2</li>
|
||||
<li>185.187.152.9 (anycast) 57.129.65.223 (2.ns1.grapheneos.org) — OVH de2</li>
|
||||
<li>2a05:b0c4:1::8 (anycast) 2001:41d0:701:1100::245b (2.ns1.grapheneos.org) — OVH de2</li>
|
||||
<li>185.187.152.9 (anycast) 15.235.197.61 (3.ns1.grapheneos.org) — OVH sgp2</li>
|
||||
<li>2a05:b0c4:1::8 (anycast) 2402:1f00:8000:800::3966 (3.ns1.grapheneos.org) — OVH sgp2</li>
|
||||
<li>198.251.90.93 (anycast), 198.98.53.141 (0.ns2.grapheneos.org) — BuyVM New York</li>
|
||||
<li>2605:6400:10:102e:95bc:89ef:2e7f:49bb (0.ns2.grapheneos.org) — BuyVM New York</li>
|
||||
<li>198.251.90.93 (anycast), 205.185.124.155 (1.ns2.grapheneos.org) — BuyVM Las Vegas</li>
|
||||
<li>2605:6400:20:1c8f:a0c9:372d:482e:945b (1.ns2.grapheneos.org) — BuyVM Las Vegas</li>
|
||||
<li>198.251.90.93 (anycast), 107.189.3.168 (2.ns2.grapheneos.org) — BuyVM Luxembourg</li>
|
||||
<li>2605:6400:30:ec25:102c:af6d:5be:1eb8 (2.ns2.grapheneos.org) — BuyVM Luxembourg</li>
|
||||
</ul>
|
||||
|
||||
<p>Ports:</p>
|
||||
|
||||
<ul>
|
||||
<li>TCP 22 ssh</li>
|
||||
<li>TCP 53 domain</li>
|
||||
<li>UDP 53 domain</li>
|
||||
<li>TCP 80 http</li>
|
||||
<li>TCP 443 https</li>
|
||||
<li>TCP 853 domain-s</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="ns1.staging.grapheneos.org">
|
||||
<h2><a href="#ns1.staging.grapheneos.org">Staging GrapheneOS DNS server</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/ns1.grapheneos.org">Repository</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/ns1.grapheneos.org/issues">Issue tracker</a></li>
|
||||
</ul>
|
||||
|
||||
<p>Specs:</p>
|
||||
|
||||
<ul>
|
||||
<li>BuyVM Slice 1024</li>
|
||||
<li>1 core</li>
|
||||
<li>1 GB memory</li>
|
||||
<li>20 GB NVMe SSD storage</li>
|
||||
<li>1000 Mbit/s bandwidth</li>
|
||||
</ul>
|
||||
|
||||
<p>Domains:</p>
|
||||
|
||||
<ul>
|
||||
<li>ns1.staging.attestation.app</li>
|
||||
<li>ns2.staging.attestation.app</li>
|
||||
<li>ns1.staging.grapheneos.org</li>
|
||||
<li>ns2.staging.grapheneos.org</li>
|
||||
</ul>
|
||||
|
||||
<p>IPs:</p>
|
||||
|
||||
<ul>
|
||||
<li>198.98.56.238 — BuyVM New York</li>
|
||||
<li>2605:6400:10:c41:de92:c534:326a:711a — BuyVM New York</li>
|
||||
</ul>
|
||||
|
||||
<p>Ports:</p>
|
||||
|
||||
<ul>
|
||||
<li>TCP 22 ssh</li>
|
||||
<li>TCP 53 domain</li>
|
||||
<li>UDP 53 domain</li>
|
||||
<li>TCP 80 http</li>
|
||||
<li>TCP 443 https</li>
|
||||
<li>TCP 853 domain-s</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="attestation.app">
|
||||
<h2><a href="#attestation.app">Attestation website and service</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/AttestationServer">Repository</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/AttestationServer/issues">Issue tracker</a></li>
|
||||
</ul>
|
||||
|
||||
<p>Specs:</p>
|
||||
|
||||
<ul>
|
||||
<li>OVH VPS vps2023-le-4</li>
|
||||
<li>4 core</li>
|
||||
<li>4 GB memory</li>
|
||||
<li>80 GB NVMe SSD storage</li>
|
||||
<li>1000 Mbit/s bandwidth</li>
|
||||
</ul>
|
||||
|
||||
<p>Domains:</p>
|
||||
|
||||
<ul>
|
||||
<li>attestation.app</li>
|
||||
<li>www.attestation.app</li>
|
||||
</ul>
|
||||
|
||||
<p>IPs:</p>
|
||||
|
||||
<ul>
|
||||
<li>51.79.66.27 — OVH bhs6</li>
|
||||
<li>2607:5300:205:200::7e9 — OVH bhs6</li>
|
||||
</ul>
|
||||
|
||||
<p>Ports:</p>
|
||||
|
||||
<ul>
|
||||
<li>TCP 22 ssh</li>
|
||||
<li>TCP 80 http</li>
|
||||
<li>TCP 443 https</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="staging.attestation.app">
|
||||
<h2><a href="#staging.attestation.app">Staging attestation website and service</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/AttestationServer">Repository</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/AttestationServer/issues">Issue tracker</a></li>
|
||||
</ul>
|
||||
|
||||
<p>Specs:</p>
|
||||
|
||||
<ul>
|
||||
<li>BuyVM Slice 1024</li>
|
||||
<li>1 core</li>
|
||||
<li>1 GB memory</li>
|
||||
<li>20 GB NVMe SSD storage</li>
|
||||
<li>1000 Mbit/s bandwidth</li>
|
||||
</ul>
|
||||
|
||||
<p>Domains:</p>
|
||||
|
||||
<ul>
|
||||
<li>staging.attestation.app</li>
|
||||
</ul>
|
||||
|
||||
<p>IPs:</p>
|
||||
|
||||
<ul>
|
||||
<li>198.98.57.157 — BuyVM New York</li>
|
||||
<li>2605:6400:10:aa9:1c0f:44d3:da15:c0ec — BuyVM New York</li>
|
||||
</ul>
|
||||
|
||||
<p>Ports:</p>
|
||||
|
||||
<ul>
|
||||
<li>TCP 22 ssh</li>
|
||||
<li>TCP 80 http</li>
|
||||
<li>TCP 443 https</li>
|
||||
</ul>
|
||||
</section>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
@ -1,66 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Articles | GrapheneOS</title>
|
||||
<meta name="description" content="Articles on assorted topics related to GrapheneOS."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="Articles | GrapheneOS"/>
|
||||
<meta property="og:description" content="Articles on assorted topics related to GrapheneOS."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/articles/"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/articles/"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
</head>
|
||||
<body>
|
||||
{% with current_page="articles" %}
|
||||
{% include "header.html" %}
|
||||
{% endwith %}
|
||||
<main id="articles">
|
||||
<h1><a href="#articles">Articles</a></h1>
|
||||
|
||||
<p>The main documentation for GrapheneOS is at the top-level of the site:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="/features">Features overview</a> — Overview of GrapheneOS features differentiating it from the Android Open Source Project.</li>
|
||||
<li><a href="/install/">Install</a> — Installation instructions for GrapheneOS.</li>
|
||||
<li><a href="/build">Build</a> — Building instructions for GrapheneOS.</li>
|
||||
<li><a href="/usage">Usage guide</a> — Usage instructions for GrapheneOS.</li>
|
||||
<li><a href="/faq">Frequently Asked Questions</a> — Answers to frequently asked questions about GrapheneOS.</li>
|
||||
<li><a href="/releases#changelog">Releases changelog</a> — Changelog for official releases of GrapheneOS.</li>
|
||||
<li><a href="/source">Source code</a> — Documenting all source code repositories for GrapheneOS.</li>
|
||||
<li><a href="/history/">History</a> — History of the GrapheneOS project.</li>
|
||||
</ul>
|
||||
|
||||
<p>Our attestation service has <a href="https://attestation.app/about">a page
|
||||
explaining how the Auditor app and attestation service work</a>.</p>
|
||||
|
||||
<p>Other articles on assorted topics related to GrapheneOS:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="/articles/attestation-compatibility-guide">Attestation compatibility guide</a> — Guide on using remote attestation in a way that's compatible with GrapheneOS</li>
|
||||
<li><a href="/articles/grapheneos-servers">GrapheneOS servers</a> — Documentation on GrapheneOS servers.</li>
|
||||
<li><a href="/articles/server-traffic-shaping">Server traffic shaping</a> — Implementing server traffic shaping on Linux with CAKE.</li>
|
||||
<li><a href="/articles/sitewide-advertising-industry-opt-out">Sitewide advertising industry opt-out</a> — Using ads.txt / app-ads.txt to disallow buying or selling ads for a domain.</li>
|
||||
</ul>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
@ -1,89 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Positon location service | Articles | GrapheneOS</title>
|
||||
<meta name="description" content="Information about the Positon location service."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="Positon location service"/>
|
||||
<meta property="og:description" content="Information about the Positon location service."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/articles/positon-location-service"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/articles/positon-location-service"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
</head>
|
||||
<body>
|
||||
{% include "header.html" %}
|
||||
<main id="positon-location-service">
|
||||
<h1><a href="#positon-location-service">Positon location service</a></h1>
|
||||
|
||||
<p>The Positon location service is a proprietary and highly privacy invasive service
|
||||
created by developers tied to /e/OS with their funding. There's a deliberate effort to
|
||||
hide that it's tied to them in order to convince other projects to adopt it, as opposed
|
||||
to using the similar service they host for /e/OS itself. Using the service requires
|
||||
uploading sensitive location data to obtain location estimates, similar to the Apple and
|
||||
Google location services. As with the Apple and Google services, it's a centralized
|
||||
proprietary service with fully proprietary data. Unlike those services, the people
|
||||
behind it have a history of publishing notoriously insecure software such as the /e/OS
|
||||
operating system itself which massively rolls back standard security, lags years behind
|
||||
on security updates and covers all of that up. They blatantly scam their users with
|
||||
false privacy/security claims for /e/OS, and nothing different should be expected from a
|
||||
location service from the same group of people. Multiple people involved in it are also
|
||||
actively participating in harassment targeting privacy/security researchers and
|
||||
engineers including but not limited to GrapheneOS team members.</p>
|
||||
|
||||
<p>The people behind the Positon location service have repeatedly talked about the
|
||||
importance they see in centralizing the whole open source community around using their
|
||||
service while locking out alternatives to it through proprietary data. They have spread
|
||||
fear, uncertainty and doubt about making services using open mapping data through
|
||||
claiming that it's a privacy hazard for people to have access to maps of Wi-Fi networks
|
||||
publicly broadcasting their SSID despite that data already being available through many
|
||||
commercial providers including publicly queryable databases such as Wigle. Anyone can
|
||||
drive around building these maps and many companies have already built them, with the
|
||||
data available for sale, as Positon shows with them obtaining access to it. The real
|
||||
privacy hazard is sending your location in real time to a service, particularly a poorly
|
||||
secured one from people known to cover up and downplay vulnerabilities. Positon has been
|
||||
built to grab as much market share as possible early on before actual open options can
|
||||
emerge and gather the necessary data.</p>
|
||||
|
||||
<p>The people involved in Positon have only ever cared about their careers, power and
|
||||
influence. They've consistently been on a side against real privacy and security, but
|
||||
rather focused on monetizing people's demand for it and grabbing as much market share as
|
||||
they can as quickly as they can with endless false marketing and attacks on projects
|
||||
like GrapheneOS. They see GrapheneOS as a huge threat to them due to us striving to
|
||||
bring people real privacy and security at no cost, which is far easier to obtain and
|
||||
use. This invalidates the business model of their companies like Murena. They
|
||||
consistently use their non-profits mainly as a way to earn money and promote their
|
||||
for-profit initiatives.</p>
|
||||
|
||||
<p>The service claims to be free of charge, but a core goal is turning it into a way to
|
||||
get data from users to build their own database that's largely not going to be available
|
||||
for use by others. Using it is helping them build a future business at the expense of
|
||||
user privacy, little different from the Apple and Google services. This is not what the
|
||||
open source community needs from a location service. The claims of no strings attached
|
||||
and the implication that it's open are nonsense. Storing as little data as possible
|
||||
would mean using local database for the region, not a network-based service. They're
|
||||
opposed to doing a local service well rather than it being their long term goal. They
|
||||
explicitly aim to lock out other alternatives and deter local location detection via
|
||||
Wi-Fi.</p>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
@ -1,259 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Server traffic shaping | Articles | GrapheneOS</title>
|
||||
<meta name="description" content="Implementing server traffic shaping on Linux with CAKE."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="Server traffic shaping"/>
|
||||
<meta property="og:description" content="Implementing server traffic shaping on Linux with CAKE."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/articles/server-traffic-shaping"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/articles/server-traffic-shaping"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
</head>
|
||||
<body>
|
||||
{% include "header.html" %}
|
||||
<main id="server-traffic-shaping">
|
||||
<h1><a href="#server-traffic-shaping">Server traffic shaping</a></h1>
|
||||
|
||||
<p>This article covers implementing server traffic shaping on Linux with CAKE. The aim
|
||||
is to provide fair usage of bandwidth between clients and consistently low latency
|
||||
for dedicated and virtual servers provided by companies like OVH and others.</p>
|
||||
|
||||
<p>Traffic shaping is generally discussed in the context of a router shaping traffic
|
||||
for a local network with assorted clients connected. It also has a lot to offer on a
|
||||
server where you don't control the network. If you control your own infrastructure
|
||||
from the server to the ISP, you probably want to do this on the routers instead.</p>
|
||||
|
||||
<p>This article was motivated by the serious lack of up-to-date information on this
|
||||
topic elsewhere. It's very easy to implement on modern Linux kernels and the results
|
||||
are impressive from extremely simple test cases to heavily loaded servers.</p>
|
||||
|
||||
<section id="problem">
|
||||
<h2><a href="#problem">Problem</a></h2>
|
||||
|
||||
<p>A server will generally be provisioned with a specific amount of bandwidth
|
||||
enforced by a router in close proximity. This router acts as the bottleneck and
|
||||
ends up being in charge of most of the queuing and congestion decisions. Unless
|
||||
that's under your control, the best you can hope for is that the router is
|
||||
configured to use <code>fq_codel</code> as the queuing discipline (qdisc) to
|
||||
provide fair queuing between streams and low latency by preventing a substantial
|
||||
backlog of data.</p>
|
||||
|
||||
<p>Unfortunately, the Linux kernel still defaults to <code>pfifo_fast</code>
|
||||
instead of the much saner <code>fq_codel</code> algorithm. This is changed by a
|
||||
configuration file shipped with systemd, so <em>most</em> distributions using
|
||||
systemd as init end up with a sane default. Debian removes that configuration and
|
||||
doesn't set a sane default itself, and is widely used. Many server providers like
|
||||
OVH do not appear to consistently use modern queue disciplines like
|
||||
<code>fq_codel</code> within their networks, particularly at artificial
|
||||
bottlenecks implementing rate limiting based on product tiers.</p>
|
||||
|
||||
<p>If the bottleneck doesn't use fair queuing, division of bandwidth across
|
||||
streams is very arbitrary and latency suffers under congestion. These issues are
|
||||
often referred to as bufferbloat, and <code>fq_codel</code> is quite good at
|
||||
resolving it.</p>
|
||||
|
||||
<p>The <code>fq_codel</code> algorithm is far from perfect. It has issues with
|
||||
hash collisions and more importantly only does fair queuing between streams.
|
||||
Buffer bloat also isn't the only relevant issue. Clients with multiple connections
|
||||
receive more bandwidth and a client can open a large number of connections to
|
||||
maximize their bandwidth usage at the expense of others. Fair queuing is important
|
||||
beyond as a solution to bufferbloat and there's more to fair queuing than doing it
|
||||
only based on streams.</p>
|
||||
|
||||
<p>Traditionally, web browsers open a bunch of HTTP/1.1 connections to each server
|
||||
which ends up giving them an unfair amount of bandwidth. HTTP/2 is much friendlier
|
||||
since it uses a single connection to each server for the entire browser. Download
|
||||
managers take this to the extreme and intentionally use many connections to bypass
|
||||
server limits and game the division of resources between clients.</p>
|
||||
</section>
|
||||
|
||||
<section id="solution">
|
||||
<h2><a href="#solution">Solution</a></h2>
|
||||
|
||||
<p>Linux 4.19 and later makes it easy to solve all of these problems. The CAKE
|
||||
queuing discipline provides sophisticated fair queuing based on destination and
|
||||
source addresses with finer-grained fairness for individual streams.</p>
|
||||
|
||||
<p> Unfortunately, simply enabling it as your queuing discipline isn't enough
|
||||
since it's highly unlikely that your server is the network bottleneck. You need to
|
||||
configure it with a bandwidth limit based on the provisioned bandwidth to move the
|
||||
bottleneck under your control where you can control how traffic is queued.</p>
|
||||
</section>
|
||||
|
||||
<section id="results">
|
||||
<h2><a href="#results">Results</a></h2>
|
||||
|
||||
<p>We've used an 100mbit OVH server for as a test platform for a case where
|
||||
clients can easily max out the server bandwidth on their own. As a very simple
|
||||
example, consider 2 clients with more than 100mbit of bandwidth each downloading a
|
||||
large file. These are (rounded) real world results with CAKE:</p>
|
||||
|
||||
<ul>
|
||||
<li>client A with 1 connection gets 50mbit</li>
|
||||
<li>client B with 10 connections gets 5mbit each adding up to 50mbit</li>
|
||||
</ul>
|
||||
|
||||
<p>CAKE with <code>flows</code> instead of the default <code>triple-isolate</code> to
|
||||
mimic <code>fq_codel</code> at a bottleneck:</p>
|
||||
|
||||
<ul>
|
||||
<li>client A with 1 connection gets 9mbit</li>
|
||||
<li>client B with 10 connections gets 9mbit each adding up to 90mbit</li>
|
||||
</ul>
|
||||
|
||||
<p>The situation without traffic shaping is a mess. Latency takes a serious hit
|
||||
that's very noticeable via SSH. Bandwidth is consistently allocated very unevenly
|
||||
and ends up fluctuating substantially between test runs. The connections tend to
|
||||
settle near a rate, often significantly lower or higher than the fair 9mbit
|
||||
amount. It's generally something like this, but the range varies a lot:</p>
|
||||
|
||||
<ul>
|
||||
<li>client A with 1 connection gets ~6mbit to ~14mbit</li>
|
||||
<li>client B with 10 connections gets ~6mbit to ~14mbit each adding up to ~86mbit
|
||||
to ~94mbit</li>
|
||||
</ul>
|
||||
|
||||
<p>CAKE continues working as expected with a far higher number of connections. It
|
||||
technically has a higher CPU cost than <code>fq_codel</code>, but that's much more
|
||||
of a concern for low end router hardware. It hardly matters on a server, even one
|
||||
that's under heavy CPU load. The improvement in user experience is substantial and
|
||||
it's very noticeable in web page load speeds when a server is under load.</p>
|
||||
</section>
|
||||
|
||||
<section id="implementation">
|
||||
<h2><a href="#implementation">Implementation</a></h2>
|
||||
|
||||
<p>For a server with 2000mbit of bandwidth provisioned, you could start by trying
|
||||
it with 99.75% of the provisioned bandwidth:</p>
|
||||
|
||||
<pre>tc qdisc replace dev eth0 root cake bandwidth 1995mbit besteffort</pre>
|
||||
|
||||
<p>On a server, setting it to use 100% of the provisioned bandwidth may work fine
|
||||
in practice. Unlike a local network connected to a consumer ISP, you shouldn't
|
||||
need to sacrifice anywhere close to the typically recommended 5-10% of your
|
||||
bandwidth for traffic shaping.</p>
|
||||
|
||||
<p>This also sets <code>besteffort</code> for the common case where the server
|
||||
doesn't have appropriate Quality of Service markings set up via Diffserv. Fair
|
||||
scheduling is already great at providing low latency by cycling through the hosts
|
||||
and streams without needing this kind of configuration. The defaults for Diffserv
|
||||
traffic classes like real-time video are set up to yield substantial bandwidth in
|
||||
exchange for lower latency. It's easy to set this up wrong and it usually won't
|
||||
make much sense on a server. You might want to set up marking low priority traffic
|
||||
like system updates, but it will already get a tiny share of the overall traffic
|
||||
on a loaded server due to fair scheduling between hosts and streams.</p>
|
||||
|
||||
<p>You can use the <code>tc -s qdisc</code> command to monitor CAKE:</p>
|
||||
|
||||
<pre>tc -s qdisc show dev eth0</pre>
|
||||
|
||||
<p>If you want to keep an eye on how it changes over time:</p>
|
||||
|
||||
<pre>watch -n 1 tc -s qdisc show dev eth0</pre>
|
||||
|
||||
<p>This is very helpful for figuring out if you've successfully moved the
|
||||
bottleneck to the server. If the bandwidth is being fully used, it should
|
||||
consistently have a backlog of data where it's applying the queuing discipline.
|
||||
The backlog shouldn't be draining to near zero under full bandwidth usage as that
|
||||
indicates the bottleneck is the server application itself or a different network
|
||||
bottleneck.</p>
|
||||
|
||||
<p>If you use systemd-network, you can add a CAKE configuration section to the
|
||||
network configuration file instead of manually running the <code>tc</code> command
|
||||
with a <code>Type=oneshot</code> service on boot:</p>
|
||||
|
||||
<pre>[CAKE]
|
||||
Bandwidth=1995M
|
||||
PriorityQueueingPreset=besteffort</pre>
|
||||
</section>
|
||||
|
||||
<section id="quicker-backpressure-propagation">
|
||||
<h2><a href="#quicker-backpressure-propagation">Quicker backpressure propagation</a></h2>
|
||||
|
||||
<p>The Linux kernel can be tuned to more quickly propagate TCP backpressure up to
|
||||
applications while still maximizing bandwidth usage. This is incredibly useful for
|
||||
interactive applications aiming to send the freshest possible copy of data and for
|
||||
protocols like HTTP/2 multiplexing streams/messages with different priorities over
|
||||
the same TCP connection. This can also substantially reduce memory usage for TCP
|
||||
by reducing buffer sizes closer to the optimal amount for maximizing bandwidth
|
||||
use without wasting memory. The downside to quicker backpressure propagation is
|
||||
increased CPU usage from additional system calls and context switches.</p>
|
||||
|
||||
<p>The Linux kernel automatically adjusts the size of the write queue to maximize
|
||||
bandwidth usage. The write queue is divided into unacknowledged bytes (TCP window
|
||||
size) and unsent bytes. As acknowledgements of transmitted data are received, it
|
||||
frees up space for the application to queue more data. The queue of unsent bytes
|
||||
provides the leeway needed to wake the application and obtain more data. This can
|
||||
be reduced using <code>net.ipv4.tcp_notsent_lowat</code> to reduce the default and
|
||||
the <code>TCP_NOTSENT_LOWAT</code> socket option to override it per-socket.</p>
|
||||
|
||||
<p>A reasonable choice for internet-based workloads concerned about latency and
|
||||
particularly prioritization within TCP connections but unwilling to sacrifice
|
||||
throughput is 128kiB. To configure this, set the following in
|
||||
<code>/etc/sysctl.d/local.conf</code> or another sysctl configuration file and
|
||||
load it with <code>sysctl --system</code>:</p>
|
||||
|
||||
<pre>net.ipv4.tcp_notsent_lowat = 131072</pre>
|
||||
|
||||
<p>Using values as low as 16384 can make sense to further improve latency and
|
||||
prioritization. However, it's more likely to negatively impact throughput and will
|
||||
further increase CPU usage. Use at least 128k or the default of not limiting the
|
||||
automatic unsent buffer size unless you're going to do substantial testing to make
|
||||
sure there's not a negative impact for the workload.</p>
|
||||
|
||||
<p>If you decide to use <code>tcp_notsent_lowat</code>, be aware that newer Linux
|
||||
kernels (Linux 5.0+ with a further improvement for Linux 5.10+) are recommended to
|
||||
substantially reduce system calls / context switches by not triggering the
|
||||
application to provide more data until over half the unsent byte buffer is
|
||||
empty.</p>
|
||||
</section>
|
||||
|
||||
<section id="high-link-speed">
|
||||
<h2><a href="#high-link-speed">High link speed</a></h2>
|
||||
|
||||
<p>By default, CAKE splits General Segmentation Offload (GSO) super-packets to
|
||||
reduce latency at the expense of CPU efficiency and throughput. This can create a
|
||||
bottleneck at high link speeds. We've had to disable this on the 2Gbit GrapheneOS
|
||||
update servers.</p>
|
||||
|
||||
<pre>[CAKE]
|
||||
Bandwidth=1995M
|
||||
PriorityQueueingPreset=besteffort
|
||||
SplitGSO=false</pre>
|
||||
</section>
|
||||
|
||||
<section id="future">
|
||||
<h2><a href="#future">Future</a></h2>
|
||||
|
||||
<p>Ideally, data centers would deploy CAKE throughout their networks with the
|
||||
default <code>triple-isolate</code> flow isolation. This may mean they need to use
|
||||
more powerful hardware for routing. If the natural bottlenecks used CAKE, setting
|
||||
up traffic shaping on the server wouldn't be necessary. This doesn't seem likely
|
||||
any time soon. Deploying <code>fq_codel</code> is much more realistic and tackles
|
||||
buffer bloat but not the issue of fairness between hosts rather than only
|
||||
streams.</p>
|
||||
</section>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
@ -1,65 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Sitewide advertising industry opt-out | Articles | GrapheneOS</title>
|
||||
<meta name="description" content="Using ads.txt / app-ads.txt to disallow buying or selling ads for a domain."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="Sitewide advertising industry opt-out"/>
|
||||
<meta property="og:description" content="Using ads.txt / app-ads.txt to disallow buying or selling ads for a domain."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/articles/sitewide-advertising-industry-opt-out"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/articles/sitewide-advertising-industry-opt-out"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
</head>
|
||||
<body>
|
||||
{% include "header.html" %}
|
||||
<main id="sitewide-advertising-industry-opt-out">
|
||||
<h1><a href="#sitewide-advertising-industry-opt-out">Sitewide advertising industry opt-out</a></h1>
|
||||
|
||||
<p>The <a href="https://iabtechlab.com/wp-content/uploads/2021/03/ads.txt-1.0.3.pdf">ads.txt specification</a>
|
||||
provides a way to list the authorized sellers of ads for a domain. The
|
||||
<a href="https://iabtechlab.com/wp-content/uploads/2019/03/app-ads.txt-v1.0-final-.pdf">app-ads.txt specification</a>
|
||||
extends this to cover apps tied to the domain. As a domain owner, this is a valuable
|
||||
way to crack down on fraudulent usage of your domain including by adware.</p>
|
||||
|
||||
<p>For domains without any third party advertising including those without any ads at
|
||||
all, you should serve both <code>/ads.txt</code> and <code>/app-ads.txt</code> from a
|
||||
web server with the placeholder record defined by the specification:</p>
|
||||
|
||||
<pre>placeholder.example.com, placeholder, DIRECT, placeholder</pre>
|
||||
|
||||
<p>The placeholder record formally disallows buying and selling ads on behalf of the
|
||||
domain including for any subdomains. This prevents fraudulently buying / selling ads
|
||||
for your domain anywhere that ads.txt / app-ads.txt are enforced.</p>
|
||||
|
||||
<p>It's in the interest of most ad tech companies to enforce these standards due to
|
||||
losses from ad fraud so adoption is increasingly widespread.</p>
|
||||
|
||||
<p>Browser extension malware injecting ads into sites is very common and this is a way
|
||||
for sites to hurt those malware developers where it hurts: their pocketbook.</p>
|
||||
|
||||
<p>These standards have a limited scope and were primarily created to address the cost
|
||||
of ad fraud for the advertising industry, but they do offer value for domain owners to
|
||||
protect their reputation and discourage adware.</p>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 15 KiB |
1385
static/build.html
@ -1,66 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Camera privacy policy | GrapheneOS</title>
|
||||
<meta name="description" content="Privacy policy for the GrapheneOS Camera app."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="Camera privacy policy"/>
|
||||
<meta property="og:description" content="Privacy policy for the GrapheneOS Camera app."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/camera-privacy-policy"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/camera-privacy-policy"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
</head>
|
||||
<body>
|
||||
{% include "header.html" %}
|
||||
<main id="camera-privacy-policy">
|
||||
<h1><a href="#camera-privacy-policy">Camera privacy policy</a></h1>
|
||||
|
||||
<p>This app requires the Camera permission for the core functionality of the app. The
|
||||
Microphone permission is optional and only requested when starting video recording
|
||||
without disabling "Include Audio". Video can be recorded without granting Microphone
|
||||
access as long as "Include Audio" is disabled. Geotagging is disabled by default and
|
||||
enabling it will request the Location permission. The app doesn't require access to
|
||||
your media or other files. It stores files to the profile's Media Store and requests
|
||||
that they be placed in DCIM/Camera which doesn't require a permission. You can also
|
||||
choose to change the directory which will have you choose a directory for it to use
|
||||
via the system file manager.</p>
|
||||
|
||||
<p>This app implements the system camera intent interfaces enabling other apps to use
|
||||
it to take pictures or record videos with explicit user consent. Only the resulting
|
||||
image or video explicitly captured by the user is given to the app. On Android 11 and
|
||||
later, only a system camera app can provide the system camera intents. This app is the
|
||||
system camera app on GrapheneOS where it provides that functionality. The handling of
|
||||
the intents is carefully designed to make it harder to trick users into accidentally
|
||||
capturing an image by implementing a delay.</p>
|
||||
|
||||
<p>This app does not make any network connections and doesn't use any services. The
|
||||
app will never include any analytics/telemetry or any form of data collection. No
|
||||
connections will ever be made to a service without the user requesting it. It stores
|
||||
settings internally and pictures/videos captured by the user in Android's media store
|
||||
for the profile.</p>
|
||||
|
||||
<p>Unlike nearly any other QR/barcode scanning apps, QR/barcode scanning does not open
|
||||
the resulting URL automatically.</p>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
@ -2,24 +2,22 @@
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Contact | GrapheneOS</title>
|
||||
<meta name="description" content="Contact information for GrapheneOS."/>
|
||||
<title>Contact | Hakurei</title>
|
||||
<meta name="description" content="Contact information for Hakurei."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="GrapheneOS contact information"/>
|
||||
<meta property="og:description" content="Contact information for GrapheneOS."/>
|
||||
<meta property="og:title" content="Hakurei contact information"/>
|
||||
<meta property="og:description" content="Contact information for Hakurei."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image" content="https://hakurei.app/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/contact"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/contact"/>
|
||||
<meta property="og:image:alt" content="Hakurei logo"/>
|
||||
<meta property="og:site_name" content="Hakurei"/>
|
||||
<meta property="og:url" content="https://hakurei.app/contact.html"/>
|
||||
<link rel="canonical" href="https://hakurei.app/contact.html"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
@ -27,7 +25,7 @@
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
<link rel="me" href="https://port.mk/@hakurei"/>
|
||||
</head>
|
||||
<body>
|
||||
{% with current_page="contact" %}
|
||||
@ -36,247 +34,11 @@
|
||||
<main id="contact">
|
||||
<h1><a href="#contact">Contact</a></h1>
|
||||
|
||||
<nav id="table-of-contents">
|
||||
<h2><a href="#table-of-contents">Table of contents</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#community">Community</a>
|
||||
<ul>
|
||||
<li><a href="#community-chat">Chat</a></li>
|
||||
<li><a href="#community-forum">Forum</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#contacting-the-project">Contacting the project</a></li>
|
||||
<li><a href="#hiring">Hiring</a></li>
|
||||
<li>
|
||||
<a href="#reporting-issues">Reporting issues</a>
|
||||
<ul>
|
||||
<li><a href="#standalone-apps">Standalone apps</a></li>
|
||||
<li><a href="#services">Services</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<section id="community">
|
||||
<h2><a href="#community">Community</a></h2>
|
||||
|
||||
<section id="community-chat">
|
||||
<h3><a href="#community-chat">Chat</a></h3>
|
||||
|
||||
<p>GrapheneOS has a very active community primarily based around the official
|
||||
chat rooms. Our chat rooms are bridged across Discord, Telegram and Matrix so
|
||||
you can choose your preferred platform.</p>
|
||||
|
||||
<p>Discord invite link: <a href="https://discord.com/invite/grapheneos">https://discord.com/invite/grapheneos</a>.</p>
|
||||
|
||||
<p>Telegram group: <a href="https://t.me/GrapheneOS">https://t.me/GrapheneOS</a>.</p>
|
||||
|
||||
<p>You can join the GrapheneOS Matrix space at
|
||||
<a href="https://matrix.to/#/%23community:grapheneos.org">#community:grapheneos.org</a>
|
||||
and can manually join each of the chat rooms from there.</p>
|
||||
|
||||
<p>The following 7 chat rooms are available across each platform, with the
|
||||
Matrix links to each individual room included below:</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><a href="https://matrix.to/#/%23general:grapheneos.org">#general:grapheneos.org</a></td>
|
||||
<td>Best place to request support, ask questions or get involved in the project</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://matrix.to/#/%23apps:grapheneos.org">#apps:grapheneos.org</a></td>
|
||||
<td>Discuss using third party apps and services with GrapheneOS</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://matrix.to/#/%23offtopic:grapheneos.org">#offtopic:grapheneos.org</a></td>
|
||||
<td>Discuss topics not strictly related to GrapheneOS</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://matrix.to/#/%23dev:grapheneos.org">#dev:grapheneos.org</a></td>
|
||||
<td>Discuss GrapheneOS app and OS development</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://matrix.to/#/%23testing:grapheneos.org">#testing:grapheneos.org</a></td>
|
||||
<td>Provide feedback on Alpha and Beta channel app and OS releases</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://matrix.to/#/%23releases:grapheneos.org">#releases:grapheneos.org</a></td>
|
||||
<td>Release announcements</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://matrix.to/#/%23infra:grapheneos.org">#infra:grapheneos.org</a></td>
|
||||
<td>Infrastructure monitoring and discussion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://matrix.to/#/%23media:grapheneos.org">#media:grapheneos.org</a></td>
|
||||
<td>Discuss GrapheneOS in news articles and other media coverage</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>Matrix is a federated service similar to email where you can choose your
|
||||
provider and has end-to-end encryption for private chats. Matrix can be a more
|
||||
privacy friendly option but has significant downsides including lag, weak
|
||||
moderation tools and the rooms needing to be regularly recreated due to bugs
|
||||
in the protocol for reaching consensus on room state between servers.</p>
|
||||
|
||||
<p>The experience on Discord is the best out of all the available options
|
||||
due to the way messages from the other platforms bridge to it, making
|
||||
it much easier to read. Search is also generally better on Discord,
|
||||
making it easier to look up information and previous discussions on
|
||||
specific topics. Additionally, Discord allows you to select your preferred
|
||||
release channels and devices via the roles feature in order to be
|
||||
notified when an app or OS release in the channel you are interested in.</p>
|
||||
|
||||
<p>Telegram is a good option to choose if you already have a Telegram account
|
||||
and use it. There is one Telegram group, which separates the different rooms via
|
||||
topics.</p>
|
||||
</section>
|
||||
|
||||
<section id="community-forum">
|
||||
<h3><a href="#community-forum">Forum</a></h3>
|
||||
|
||||
<p>We have an official
|
||||
<a href="https://discuss.grapheneos.org">forum</a> for longer form posts,
|
||||
which is publicly accessible and easier to search. We are
|
||||
using Flarum for our forum.</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="contacting-the-project">
|
||||
<h2><a href="#contacting-the-project">Contacting the project</a></h2>
|
||||
|
||||
<p>Do not contact us with offers to sell us products or services.</p>
|
||||
|
||||
<p>Please don't contact the GrapheneOS project or developers to request support /
|
||||
device support / features or to report bugs. Use the <a href="#community">community
|
||||
platforms</a> and <a href="#reporting-issues">issue trackers</a> listed below. The
|
||||
developers are active on the Matrix room but the broader community can usually
|
||||
answer most questions, and this allows the developers to focus their time and
|
||||
energy on the project.</p>
|
||||
|
||||
<p>Email is the preferred way to contact the project. X direct messages are
|
||||
checked much less frequently. A public @reply in a tweet is not a good way to contact
|
||||
the project. It is not considered sending a message by X and is not queued up as
|
||||
a message to be read, only as a regular notification that is likely to be missed or
|
||||
forgotten.</p>
|
||||
|
||||
<p>Please do not send multiple copies / versions of the same email to different
|
||||
addresses. Either send it to a single address or CC the other addresses. In general,
|
||||
it's the same people handling every email address, and they don't need to see multiple
|
||||
copies of the same email in their inbox.</p>
|
||||
|
||||
<p>You can contact <a href="mailto:contact@grapheneos.org">contact@grapheneos.org</a>
|
||||
for topics related to GrapheneOS. Please don't send emails unrelated to GrapheneOS to
|
||||
this address.</p>
|
||||
|
||||
<p>The <a href="mailto:security@grapheneos.org">security@grapheneos.org</a>
|
||||
address is for reporting high priority security issues related to GrapheneOS. Please
|
||||
don't send other kinds of emails to this address. It is not a way of increasing the
|
||||
priority of emails that are not security reports. Your emails will be treated as a
|
||||
much lower priority if you misuse this address.</p>
|
||||
|
||||
<p>The official X account for the project is <a
|
||||
href="https://x.com/GrapheneOS">@GrapheneOS</a> which is used for official
|
||||
announcements.</p>
|
||||
|
||||
<p>The official Mastodon account for the project is <a
|
||||
href="https://grapheneos.social/@GrapheneOS">@GrapheneOS@grapheneos.social</a> which
|
||||
is used for official announcements.</p>
|
||||
|
||||
<p>The official Bluesky account for the project is <a
|
||||
href="https://bsky.app/profile/grapheneos.org">@grapheneos.org</a> which is used for
|
||||
official announcements.</p>
|
||||
</section>
|
||||
|
||||
<section id="hiring">
|
||||
<h2><a href="#hiring">Hiring</a></h2>
|
||||
|
||||
<p>Interested in joining the GrapheneOS team? Check out our <a href="https://grapheneos.org/hiring">hiring page</a>.</p>
|
||||
</section>
|
||||
|
||||
<section id="reporting-issues">
|
||||
<h2><a href="#reporting-issues">Reporting issues</a></h2>
|
||||
|
||||
<p>Most issues should be reported to the global OS issue tracker for GrapheneOS
|
||||
sub-projects. However, standalone projects and anything outside of the GrapheneOS
|
||||
source tree (like the websites) has a dedicated issue tracker. The issue trackers are
|
||||
listed for reference:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/os-issue-tracker/issues">OS issue tracker</a> for all GrapheneOS repositories that are not standalone projects</li>
|
||||
<li><a href="https://github.com/GrapheneOS/hardened_malloc/issues">hardened_malloc issue tracker</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_Updater/issues">Update client issue tracker</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_SetupWizard2/issues">Setup wizard issue tracker</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/talkback/issues">Talkback issue tracker</a></li>
|
||||
</ul>
|
||||
|
||||
<section id="standalone-apps">
|
||||
<h3><a href="#standalone-apps">Standalone apps</a></h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/AppStore/issues">App Store issue tracker</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/Auditor/issues">Auditor issue tracker</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/Camera/issues">Camera app issue tracker</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/Messaging/issues">Messaging app issue tracker</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/PdfViewer/issues">PDF Viewer issue tracker</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/Vanadium/issues">Vanadium (Chromium variant) issue tracker</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="services">
|
||||
<h3><a href="#services">Services</a></h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/infrastructure/issues">Server infrastructure issue tracker (for issues applying across services)</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/AttestationServer/issues">AttestationServer (attestation.app) issue tracker</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/grapheneos.org/issues">GrapheneOS site (grapheneos.org) issue tracker</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/releases.grapheneos.org/issues">Update server (releases.grapheneos.org) issue tracker</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/grapheneos.network/issues">Connectivity check / time server (grapheneos.network) issue tracker</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/mail.grapheneos.org/issues">Mail server (mail.grapheneos.org) issue tracker</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/apps.grapheneos.org/issues">App repository (apps.grapheneos.org) issue tracker</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/matrix.grapheneos.org/issues">GrapheneOS Matrix server (matrix.grapheneos.org) issue tracker</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/discuss.grapheneos.org/issues">GrapheneOS discussion forum (discuss.grapheneos.org) issue tracker</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
<p>Hakurei maintainers are reachable via <a href="mailto:hakurei@gensokyo.uk">hakurei@gensokyo.uk</a>.
|
||||
You may request for an account on the <a href="https://git.gensokyo.uk/" target="_blank">Gensokyo Gitea</a>
|
||||
instance. Otherwise, contributions via email are welcome as well.</p>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Organization",
|
||||
"@id": "https://grapheneos.org/#organization",
|
||||
"name": "GrapheneOS",
|
||||
"description": "GrapheneOS is an open source project focused on mobile privacy and security.",
|
||||
"url": "https://grapheneos.org/",
|
||||
"logo": "https://grapheneos.org/logo.png",
|
||||
"email": "contact@grapheneos.org",
|
||||
"sameAs": [
|
||||
"https://discuss.grapheneos.org/u/GrapheneOS",
|
||||
"https://x.com/GrapheneOS",
|
||||
"https://grapheneos.social/@GrapheneOS",
|
||||
"https://bsky.app/profile/grapheneos.org",
|
||||
"https://cohost.org/GrapheneOS",
|
||||
"https://github.com/GrapheneOS",
|
||||
"https://reddit.com/u/GrapheneOS",
|
||||
"https://discord.com/invite/grapheneos",
|
||||
"https://discord.com/servers/grapheneos-private-and-secure-mobile-os-1176414688112820234",
|
||||
"https://t.me/GrapheneOS",
|
||||
"https://www.linkedin.com/company/grapheneos/",
|
||||
"https://www.facebook.com/GrapheneOS",
|
||||
"https://www.instagram.com/grapheneos/",
|
||||
"https://www.threads.net/@grapheneos",
|
||||
"https://www.youtube.com/channel/UCoZjKwzqhlir_vWeZwvl8CQ",
|
||||
"https://www.youtube.com/@GrapheneOS",
|
||||
"https://g.page/r/CeQbRTxotybUEAE",
|
||||
"https://linktr.ee/grapheneos",
|
||||
"https://en.wikipedia.org/wiki/GrapheneOS",
|
||||
"https://www.wikidata.org/wiki/Q85764357"
|
||||
],
|
||||
"foundingDate": "2014"
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 378 B |
Before Width: | Height: | Size: 419 B |
Before Width: | Height: | Size: 372 B |
Before Width: | Height: | Size: 371 B |
Before Width: | Height: | Size: 233 B |
Before Width: | Height: | Size: 378 B |
Before Width: | Height: | Size: 483 B |
Before Width: | Height: | Size: 373 B |
@ -1,422 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Donate | GrapheneOS</title>
|
||||
<meta name="description" content="Donating to support development of GrapheneOS."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="GrapheneOS donations"/>
|
||||
<meta property="og:description" content="Donating to support development of GrapheneOS."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/donate"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/donate"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
</head>
|
||||
<body>
|
||||
{% with current_page="donate" %}
|
||||
{% include "header.html" %}
|
||||
{% endwith %}
|
||||
<main id="donate">
|
||||
<h1><a href="#donate">Donate</a></h1>
|
||||
|
||||
<p>GrapheneOS is an open source project supported via donations from individuals,
|
||||
companies and other organizations. Donations are used for paying developers,
|
||||
purchasing hardware (workstations, test devices, debugging cables/boards, etc.),
|
||||
paying for infrastructure (domains, virtual/dedicated servers) and paying legal
|
||||
fees.</p>
|
||||
|
||||
<p>The multiple ways to donate are listed in the sections on this page.</p>
|
||||
|
||||
<nav id="table-of-contents">
|
||||
<h2><a href="#table-of-contents">Table of contents</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#github">GitHub Sponsors (credit card)</a></li>
|
||||
<li><a href="#bitcoin">Bitcoin</a></li>
|
||||
<li><a href="#monero">Monero</a></li>
|
||||
<li><a href="#zcash">Zcash</a></li>
|
||||
<li><a href="#ethereum">Ethereum</a></li>
|
||||
<li><a href="#cardano">Cardano</a></li>
|
||||
<li><a href="#litecoin">Litecoin</a></li>
|
||||
<li><a href="#wise">Local Bank Transfer to Wise</a></li>
|
||||
<li><a href="#paypal">PayPal</a></li>
|
||||
<li><a href="#e-transfer">Interac e-Transfer</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<section id="github">
|
||||
<h2><a href="#github">GitHub Sponsors (credit card)</a></h2>
|
||||
|
||||
<p>GrapheneOS can be sponsored with recurring or one-time donations via credit
|
||||
cards through <a href="https://github.com/sponsors/thestinger">GitHub
|
||||
Sponsors</a>. There are standard tiers from $5 to $5,000 or you can donate a custom
|
||||
amount.</p>
|
||||
</section>
|
||||
|
||||
<section id="bitcoin">
|
||||
<h2><a href="#bitcoin">Bitcoin</a></h2>
|
||||
|
||||
<p>Bitcoin can be used to make donations to the non-profit GrapheneOS
|
||||
Foundation.</p>
|
||||
|
||||
<p>You can send Bitcoin donations to the following Bech32 (Segwit) address:</p>
|
||||
|
||||
<div class="coin-address">
|
||||
<a href="bitcoin:bc1q9qw3g8tdxf3dugkv2z8cahd3axehph0mhsqk96?label=GrapheneOS%20Foundation&message=Donation%20to%20GrapheneOS%20Foundation" rel="nofollow">
|
||||
<img src="/donate-bitcoin.png?1" alt="Bitcoin donation QR code"/>
|
||||
<p>bc1q9qw3g8tdxf3dugkv2z8cahd3axehph0mhsqk96</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p>Alternatively, you can donate to the following Bech32m (Taproot) address if
|
||||
your wallet supports it (preferred):</p>
|
||||
|
||||
<div class="coin-address">
|
||||
<a href="bitcoin:bc1prqf5hks5dnd4j87wxw3djn20559yhj7wvvcv6fqxpwlg96udkzgqtamhry?label=GrapheneOS%20Foundation&message=Donation%20to%20GrapheneOS%20Foundation" rel="nofollow">
|
||||
<img src="/donate-bitcoin-taproot.png?1" alt="Bitcoin Taproot donation QR code"/>
|
||||
<p>bc1prqf5hks5dnd4j87wxw3djn20559yhj7wvvcv6fqxpwlg96udkzgqtamhry</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p>You can donate to the following BIP47 payment code (stealth address) or PayNym
|
||||
if your wallet supports it:</p>
|
||||
|
||||
<div class="coin-address">
|
||||
<a href="bitcoin:PM8TJKmhJNQX6UTFagyuBk8UGmwKM6yDovEokpHBscPgP3Ac7WdK5zaQKh5XLSawyxiGYZS2a7HkAoeL6oHg7Ahn1VXX888yRG4PwF1dojouPtW7tEHT" rel="nofollow">
|
||||
<img src="/donate-bitcoin-bip47.png" alt="Bitcoin BIP47 payment code QR code"/>
|
||||
<p>PM8TJKmhJNQX6UTFagyuBk8UGmwKM6yDovEokpHBscPgP3Ac7WdK5zaQKh5XLSawyxiGYZS2a7HkAoeL6oHg7Ahn1VXX888yRG4PwF1dojouPtW7tEHT</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p>PayNym: <var>+GrapheneOS</var></p>
|
||||
</section>
|
||||
|
||||
<section id="monero">
|
||||
<h2><a href="#monero">Monero</a></h2>
|
||||
|
||||
<p>Monero can be used to make donations to the non-profit GrapheneOS
|
||||
Foundation.</p>
|
||||
|
||||
<p>You can send Monero donations to the following address:</p>
|
||||
|
||||
<div class="coin-address">
|
||||
<a href="monero:862CebHaBpFPgYoNC6zw4U8rsXrDjD8s5LMJNS7yVCRHMUKr9dDi7adMSLUMjkDYJ85xahQTCJHHyK5RCvvRJu9x7iSzN9D?recipient_name=GrapheneOS%20Foundation&tx_description=Donation%20to%20GrapheneOS%20Foundation" rel="nofollow">
|
||||
<img src="/donate-monero.png?1" alt="Monero donation QR code"/>
|
||||
<p>862CebHaBpFPgYoNC6zw4U8rsXrDjD8s5LMJNS7yVCRHMUKr9dDi7adMSLUMjkDYJ85xahQTCJHHyK5RCvvRJu9x7iSzN9D</p>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="zcash">
|
||||
<h2><a href="#zcash">Zcash</a></h2>
|
||||
|
||||
<p>Zcash can be used to make donations to the non-profit GrapheneOS
|
||||
Foundation.</p>
|
||||
|
||||
<p>You can send Zcash donations to the following transparent address:</p>
|
||||
|
||||
<div class="coin-address">
|
||||
<a href="zcash:t1SJABjX8rqgzqgrzLW5dUw7ikSDZ2snD8A?label=GrapheneOS%20Foundation&message=Donation%20to%20GrapheneOS%20Foundation" rel="nofollow">
|
||||
<img src="/donate-zcash-transparent.png?1" alt="Transparent Zcash donation QR code"/>
|
||||
<p>t1SJABjX8rqgzqgrzLW5dUw7ikSDZ2snD8A</p>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="ethereum">
|
||||
<h2><a href="#ethereum">Ethereum</a></h2>
|
||||
|
||||
<p>Ethereum can be used to make donations to the non-profit GrapheneOS
|
||||
Foundation.</p>
|
||||
|
||||
<p>You can send Ethereum donations to the following address:</p>
|
||||
|
||||
<div class="coin-address">
|
||||
<a href="ethereum:0xC822A62E5Ab443E0001f30cEB9B2336D0524fC61" rel="nofollow">
|
||||
<img src="/donate-ethereum.png?1" alt="Ethereum donation QR code"/>
|
||||
<p>0xC822A62E5Ab443E0001f30cEB9B2336D0524fC61</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p><strong>We aren't looking for donations of tokens, only Ethereum itself.</strong></p>
|
||||
</section>
|
||||
|
||||
<section id="cardano">
|
||||
<h2><a href="#cardano">Cardano</a></h2>
|
||||
|
||||
<p>Cardano can be used to make donations to the non-profit GrapheneOS
|
||||
Foundation.</p>
|
||||
|
||||
<p>You can send Cardano donations to the following address:</p>
|
||||
|
||||
<div class="coin-address">
|
||||
<a href="web+cardano:addr1q9v89vfwyfssveug5zf2w7leafz8ethq490gvq0ghag883atfnucytpnq2t38dj7cnyngs6ne05cdwu9gseevgmt3ggq2a2wt6" rel="nofollow">
|
||||
<img src="/donate-cardano.png?1" alt="Cardano donation QR code"/>
|
||||
<p>addr1q9v89vfwyfssveug5zf2w7leafz8ethq490gvq0ghag883atfnucytpnq2t38dj7cnyngs6ne05cdwu9gseevgmt3ggq2a2wt6</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p>We own the <var>$grapheneos</var> handle with this address so you can also send to the handle.</p>
|
||||
|
||||
<p><strong>We aren't looking for donations of tokens, only Cardano itself.</strong></p>
|
||||
</section>
|
||||
|
||||
<section id="litecoin">
|
||||
<h2><a href="#litecoin">Litecoin</a></h2>
|
||||
|
||||
<p>Litecoin can be used to make donations to the non-profit GrapheneOS
|
||||
Foundation.</p>
|
||||
|
||||
<p>You can send Litecoin donations to the following Bech32 (Segwit) address:</p>
|
||||
|
||||
<div class="coin-address">
|
||||
<a href="litecoin:ltc1qzssmqueth6zjzr95rkluy5xdx9q4lk8vyrvea9?label=GrapheneOS%20Foundation&message=Donation%20to%20GrapheneOS%20Foundation" rel="nofollow">
|
||||
<img src="/donate-litecoin.png" alt="Litecoin donation QR code"/>
|
||||
<p>ltc1qzssmqueth6zjzr95rkluy5xdx9q4lk8vyrvea9</p>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="wise">
|
||||
<h2><a href="#wise">Local Bank Transfer to Wise</a></h2>
|
||||
|
||||
<p>You can donate to the non-profit GrapheneOS Foundation via local bank transfers
|
||||
to our Wise account in the EU/SEPA, UK, US, Australia, New Zealand, Canada,
|
||||
Hungary and Turkey.</p>
|
||||
|
||||
<section id="wise-sepa">
|
||||
<h2><a href="#wise-sepa">EU/SEPA (EUR)</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt>Account holder</dt>
|
||||
<dd>GrapheneOS Foundation</dd>
|
||||
|
||||
<dt>IBAN</dt>
|
||||
<dd>BE20 9677 1140 7056</dd>
|
||||
|
||||
<dt>BIC</dt>
|
||||
<dd>TRWIBEB1XXX</dd>
|
||||
|
||||
<dt>Bank name</dt>
|
||||
<dd>Wise Europe SA</dd>
|
||||
|
||||
<dt>Wise and Bank address</dt>
|
||||
<dd>Rue du Trône 100, 3rd floor<br/>Brussels<br/>1050<br/>Belgium</dd>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section id="wise-uk">
|
||||
<h2><a href="#wise-uk">UK (GBP)</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt>Account holder</dt>
|
||||
<dd>GrapheneOS Foundation</dd>
|
||||
|
||||
<dt>Account number</dt>
|
||||
<dd>49883070</dd>
|
||||
|
||||
<dt>IBAN</dt>
|
||||
<dd>GB68 TRWI 2314 7049 8830 70</dd>
|
||||
|
||||
<dt>Sort code</dt>
|
||||
<dd>23-14-70</dd>
|
||||
|
||||
<dt>Bank name</dt>
|
||||
<dd>Wise Payments Limited</dd>
|
||||
|
||||
<dt>Wise and Bank address</dt>
|
||||
<dd>56 Shoreditch High Street<br/>London<br/>E1 6JJ<br/>United Kingdom</dd>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section id="wise-us">
|
||||
<h2><a href="#wise-us">US (USD)</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt>Account holder</dt>
|
||||
<dd>GrapheneOS Foundation</dd>
|
||||
|
||||
<dt>Account number</dt>
|
||||
<dd>8313560023</dd>
|
||||
|
||||
<dt>Routing number</dt>
|
||||
<dd>026073150</dd>
|
||||
|
||||
<dt>Account type</dt>
|
||||
<dd>Checking</dd>
|
||||
|
||||
<dt>Wise address</dt>
|
||||
<dd>30 W. 26th Street, Sixth Floor<br/>New York NY<br/>10010<br/>United States</dd>
|
||||
|
||||
<dt>Bank name</dt>
|
||||
<dd>Community Federal Savings Bank</dd>
|
||||
|
||||
<dt>Bank address</dt>
|
||||
<dd>89-16 Jamaica Ave<br/>Woodhaven NY<br/>11421<br/>United States</dd>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section id="wise-australia">
|
||||
<h2><a href="#wise-australia">Australia (AUD)</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt>Account holder</dt>
|
||||
<dd>GrapheneOS Foundation</dd>
|
||||
|
||||
<dt>Account number</dt>
|
||||
<dd>213524417</dd>
|
||||
|
||||
<dt>BSB code</dt>
|
||||
<dd>774-001</dd>
|
||||
|
||||
<dt>Bank name</dt>
|
||||
<dd>Wise Australia Pty Ltd</dd>
|
||||
|
||||
<dt>Wise address</dt>
|
||||
<dd>Suite 1, Level 11, 66 Goulburn Street<br/>Sydney<br/>2000<br/>Australia</dd>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section id="wise-new-zealand">
|
||||
<h2><a href="#wise-new-zealand">New Zealand (NZD)</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt>Account holder</dt>
|
||||
<dd>GrapheneOS Foundation</dd>
|
||||
|
||||
<dt>Account number</dt>
|
||||
<dd>04-2021-0151878-36</dd>
|
||||
|
||||
<dt>Wise address</dt>
|
||||
<dd>56 Shoreditch High Street<br/>London<br/>E1 6JJ<br/>United Kingdom</dd>
|
||||
|
||||
<dt>Bank name</dt>
|
||||
<dd>JPMorgan Chase</dd>
|
||||
|
||||
<dt>Bank address</dt>
|
||||
<dd>Head Office, Pwc Tower<br/>Auckland<br/>1010<br/>New Zealand</dd>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section id="wise-canada">
|
||||
<h2><a href="#wise-canada">Canada (CAD)</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt>Account holder</dt>
|
||||
<dd>GrapheneOS Foundation</dd>
|
||||
|
||||
<dt>Account number</dt>
|
||||
<dd>200110745303</dd>
|
||||
|
||||
<dt>Transit number</dt>
|
||||
<dd>16001</dd>
|
||||
|
||||
<dt>Institution number</dt>
|
||||
<dd>621</dd>
|
||||
|
||||
<dt>Wise address</dt>
|
||||
<dd>99 Bank Street, Suite 1420<br/>Ottawa ON<br/>K1P 1H4<br/>Canada</dd>
|
||||
|
||||
<dt>Bank name</dt>
|
||||
<dd>Peoples Trust</dd>
|
||||
|
||||
<dt>Bank address</dt>
|
||||
<dd>595 Burrard Street<br/>Vancouver BC<br/>V7X 1L7<br/>Canada</dd>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section id="wise-hungary">
|
||||
<h2><a href="#wise-hungary">Hungary (HUF)</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt>Account holder</dt>
|
||||
<dd>GrapheneOS Foundation</dd>
|
||||
|
||||
<dt>Account number</dt>
|
||||
<dd>12600016-11020392-99827322</dd>
|
||||
|
||||
<dt>Bank name</dt>
|
||||
<dd>Wise Europe SA</dd>
|
||||
|
||||
<dt>Wise and Bank address</dt>
|
||||
<dd>Rue du Trône 100, 3rd floor<br/>Brussels<br/>1050<br/>Belgium</dd>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section id="wise-turkey">
|
||||
<h2><a href="#wise-turkey">Turkey (TRY)</a></h2>
|
||||
|
||||
<dl>
|
||||
<dt>Account holder</dt>
|
||||
<dd>GrapheneOS Foundation</dd>
|
||||
|
||||
<dt>IBAN</dt>
|
||||
<dd>TR43 0010 3000 0000 0057 4294 70</dd>
|
||||
|
||||
<dt>Wise address</dt>
|
||||
<dd>56 Shoreditch High Street, London, E1 6JJ, United Kingdom</dd>
|
||||
|
||||
<dt>Bank name</dt>
|
||||
<dd>Fibabanka A.Ş.</dd>
|
||||
|
||||
<dt>Bank address</dt>
|
||||
<dd>Büyükdere Cad. 129<br/>Esentepe Mah.<br/>Sisli<br/>Istanbul<br/>Turkey</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="paypal">
|
||||
<h2><a href="#paypal">PayPal</a></h2>
|
||||
|
||||
<p>PayPal can be used to make one-time, monthly or yearly donations to the
|
||||
non-profit GrapheneOS Foundation.</p>
|
||||
|
||||
<p>If possible, use the donation link for your currency. If it's not listed,
|
||||
please use the CAD donation link.</p>
|
||||
|
||||
<p>Donation links:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://www.paypal.com/donate/?hosted_button_id=T8KRPYKU5QVNE">Canadian dollar (CAD)</a></li>
|
||||
<li><a href="https://www.paypal.com/donate/?hosted_button_id=2S2BP8V4E7PXU">United States dollar (USD)</a></li>
|
||||
<li><a href="https://www.paypal.com/donate/?hosted_button_id=5SNPWEDS53HW4">Euro (EUR)</a></li>
|
||||
<li><a href="https://www.paypal.com/donate/?hosted_button_id=N498QNB7NPKU8">British pound (GBP)</a></li>
|
||||
</ul>
|
||||
|
||||
<p>PayPal charges a base fee of 30 cents and 2.9% of the donation amount within
|
||||
Canada. There's an additional 0.8% fee for donations from the US and 1% for other
|
||||
countries. Currency conversion adds an additional 4% fee as opposed to the usual
|
||||
PayPal conversion fee of 3%.</p>
|
||||
</section>
|
||||
|
||||
<section id="e-transfer">
|
||||
<h2><a href="#e-transfer">Interac e-Transfer</a></h2>
|
||||
|
||||
<p>If you have a Canadian bank account, you can send Canadian dollar donations to
|
||||
the non-profit GrapheneOS Foundation via Interac e-Transfer to
|
||||
<var>contact@grapheneos.org</var>. The email address has Interac e-Transfer
|
||||
Autodeposit support enabled so no security question is necessary. If your bank
|
||||
doesn't support Autodeposit, set the answer to the security question to
|
||||
GrapheneOS.</p>
|
||||
</section>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
2067
static/faq.html
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 15 KiB |
1526
static/features.html
@ -1,86 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Hiring | GrapheneOS</title>
|
||||
<meta name="description" content="GrapheneOS job opportunities."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="GrapheneOS Hiring"/>
|
||||
<meta property="og:description" content="GrapheneOS job opportunities."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/hiring"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/hiring"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
</head>
|
||||
<body>
|
||||
{% with current_page="hiring" %}
|
||||
{% include "header.html" %}
|
||||
{% endwith %}
|
||||
<main id="hiring">
|
||||
<h1><a href="#hiring">GrapheneOS Remote Developer</a></h1>
|
||||
|
||||
<p><strong>Location:</strong> Remote</p>
|
||||
<p><strong>Position Type:</strong> Independent Contractor</p>
|
||||
|
||||
<p>We are seeking a highly skilled and self-directed developer to contribute to our open source project, someone who shares our passion for enhancing the privacy and security of mobile devices. The ideal candidate will have experience working with Android-based operating systems, the Linux kernel and its hardening, memory allocators, or extensive experience in Android app development. In this role, you will play a key role in the development and maintenance of our <a href="https://github.com/GrapheneOS">existing projects</a>, and will be expected to commit a minimum of 80 hours per month. The role will require a high level of autonomy and the ability to independently manage workloads.</p>
|
||||
|
||||
<section id="responsibilities">
|
||||
<h2><a href="#responsibilities">Responsibilities</a></h2>
|
||||
<ul>
|
||||
<li>Manage a specific aspect of the project, such as the kernel, memory allocator, custom OS features, or apps like Vanadium, Auditor, Camera, PDFViewer. Your time will be spent improving them, porting them to new Android versions, reviewing code contributions etc.</li>
|
||||
<li>Adhere to our development guidelines, available <a href="https://grapheneos.org/build#development-guidelines">here</a></li>
|
||||
<li>Collaborate with the development team to address bugs, vulnerabilities, and performance issues</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="qualifications">
|
||||
<h2><a href="#qualifications">Qualifications</a></h2>
|
||||
<ul>
|
||||
<li>Prior experience working on one or more of Android/AOSP-based operating systems, the Linux kernel and its hardening, memory allocators, or Android app development</li>
|
||||
<li>Strong programming skills in relevant languages (in order from most to least common: Java, Kotlin, C++, C, Rust, JavaScript, TypeScript, arm64 assembly, Bash, Python)</li>
|
||||
<li>Need to have enough experience to be comfortable to self direct workloads and submit finished features and fixes ready for review</li>
|
||||
<li>Commitment to privacy and security principles</li>
|
||||
<li>Ideally prior experience contributing to free and open source projects</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="time">
|
||||
<h2><a href="#time">Time Commitment</a></h2>
|
||||
<p>Must be able to commit to spending 80 hours or more a month, but we are extremely flexible about how you want to structure your working times. There is, however, a significant workload porting GrapheneOS forward when each new Android version is released. Having the capacity to focus and/or increase work hours during these periods is a great advantage.</p>
|
||||
</section>
|
||||
|
||||
<section id="salary">
|
||||
<h2><a href="#salary">Salary</a></h2>
|
||||
<p>Salary and remuneration will be commensurate with experience and aligned with industry standards. You will be employed as an independent contractor.</p>
|
||||
</section>
|
||||
|
||||
<section id="about">
|
||||
<h2><a href="#about">About GrapheneOS</a></h2>
|
||||
<p>GrapheneOS is a privacy and security-focused mobile OS with Android app compatibility developed as a non-profit open source project. It's focused on the research and development of privacy and security technology, including substantial improvements to sandboxing, exploit mitigations, and the permission model. It was founded in 2014 and was formerly known as CopperheadOS. In 2023, the GrapheneOS Foundation was established as a non-profit to help steward development over the long term.</p>
|
||||
</section>
|
||||
|
||||
<section id="apply">
|
||||
<h2><a href="#apply">How to Apply</a></h2>
|
||||
<p>Send an email to <a href="mailto:hiring@grapheneos.org">hiring@grapheneos.org</a> with a description of your background and explain why you are interested in GrapheneOS. Additionally, please share any examples of relevant work or FOSS contributions.</p>
|
||||
</section>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
@ -1,112 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>CopperheadOS | History | GrapheneOS</title>
|
||||
<meta name="description" content="GrapheneOS was previously known as CopperheadOS. It's the continuation of the original open source project."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="CopperheadOS is now GrapheneOS"/>
|
||||
<meta property="og:description" content="GrapheneOS was previously known as CopperheadOS. It's the continuation of the original open source project."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/history/copperheados"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/history/copperheados"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
</head>
|
||||
<body>
|
||||
{% include "header.html" %}
|
||||
<main id="copperheados">
|
||||
<h1><a href="#copperheados">CopperheadOS is now GrapheneOS</a></h1>
|
||||
|
||||
<p>CopperheadOS was renamed to GrapheneOS in 2019. It was temporarily known as the
|
||||
Android Hardening project in 2018 before a permanent name had been chosen. For more
|
||||
details on why the project was renamed, see <a href="/history/">our history page</a>.
|
||||
For the historical release notes of the original CopperheadOS, see
|
||||
<a href="/history/legacy-changelog">our legacy changelog page</a>. The
|
||||
<a href="https://reddit.com/r/CopperheadOS">/r/CopperheadOS subreddit</a> was
|
||||
historically the central hub of the community along with a bridged IRC/Matrix channel
|
||||
that's no longer available.</p>
|
||||
|
||||
<p>GrapheneOS is the continuation of the original open source project by the original
|
||||
development team. Our <a href="/source">source code repositories</a> have been used
|
||||
since CopperheadOS transitioned to being directly based on the Android Open Source
|
||||
Project in 2015. The prior repositories predate the CopperheadOS branding and were
|
||||
also owned by us. It can be confirmed that our repositories are the original ones from
|
||||
the GitHub network graphs showing the forks over the years.</p>
|
||||
|
||||
<section id="ownership">
|
||||
<h2><a href="#ownership">Ownership</a></h2>
|
||||
|
||||
<p>We own the historical CopperheadOS source code, documentation and accounts tied
|
||||
to the open source project. Our legacy Twitter account still needs to be returned
|
||||
to us so that it can be renamed and made into an archive.</p>
|
||||
|
||||
<p>Copperhead has no valid claim over the ownership of the source code. It was not
|
||||
developed for them. They were involved as a sponsor for the work and had
|
||||
permission to sell products based on it, similar to companies selling devices with
|
||||
GrapheneOS. We've learned a lot of lessons from what happened and are being very
|
||||
careful to avoid being strongly associated with any particular company in the
|
||||
future.</p>
|
||||
</section>
|
||||
|
||||
<section id="new-product">
|
||||
<h2><a href="#new-product">New closed source product reusing the legacy branding</a></h2>
|
||||
|
||||
<p>The new product branded as CopperheadOS is closed source and not associated with
|
||||
the original project. They took our project's previous name and copied our legacy
|
||||
source code and documentation. Attribution to us has been stripped away and they
|
||||
pretend to be the ones who created it.</p>
|
||||
|
||||
<p>They've essentially stolen the identity of our open source project and have
|
||||
invested substantial resources into misrepresenting GrapheneOS as being a new
|
||||
project. They've built a business based on taking credit for research and
|
||||
development not done by them. Substantial damage has been done to GrapheneOS
|
||||
through an organized campaign of misinformation and harassment.</p>
|
||||
</section>
|
||||
|
||||
<section id="new-copperheados-vs-grapheneos">
|
||||
<h2><a href="#new-copperheados-vs-grapheneos">New CopperheadOS vs. GrapheneOS</a></h2>
|
||||
|
||||
<p>The new CopperheadOS is a shadow of the historical GrapheneOS code. They've
|
||||
continued copying portions of our newer generation code but haven't developed any
|
||||
significant privacy or security improvements on their own. It's a poor imitation
|
||||
of the original. It has a fraction of the privacy and security improvements and
|
||||
lacks a team with an understanding of how they work. It often doesn't receive
|
||||
timely security updates. It has made serious mistakes compromising user privacy
|
||||
and security.</p>
|
||||
|
||||
<p>CopperheadOS is a paid product and has license enforcement compromising user
|
||||
privacy and security through tracking devices to implement DRM. They use the
|
||||
outrageous business model of charging users for security updates rather than
|
||||
simply selling them the software or devices with it.</p>
|
||||
|
||||
<p>GrapheneOS devices can be purchased from a bunch of different companies,
|
||||
organizations and individuals. Many of these offer customer support. Unlike
|
||||
CopperheadOS, it's still open source software and you aren't being charged to
|
||||
simply get the OS updates. Anyone can sell devices with GrapheneOS without
|
||||
permission from the project due the open source licensing. Many of these sellers
|
||||
voluntarily contribute back to the project.</p>
|
||||
|
||||
<p>GrapheneOS is far more actively developed than the new CopperheadOS and has
|
||||
substantially more resources available, including significantly more funding.</p>
|
||||
</section>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
@ -1,99 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>History | GrapheneOS</title>
|
||||
<meta name="description" content="History of the GrapheneOS project."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="GrapheneOS history"/>
|
||||
<meta property="og:description" content="History of the GrapheneOS project."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/history/"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/history/"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
</head>
|
||||
<body>
|
||||
{% with current_page="history" %}
|
||||
{% include "header.html" %}
|
||||
{% endwith %}
|
||||
<main id="history">
|
||||
<h1><a href="#history">History</a></h1>
|
||||
|
||||
<p>GrapheneOS was founded by Daniel Micay in late 2014. It started as a solo project
|
||||
incorporating his previous open source privacy/security work. The project initially
|
||||
created a port of OpenBSD malloc to Android's Bionic libc and a port of the PaX kernel
|
||||
patches to the kernels for the supported devices. It quickly expanded to having a
|
||||
large set of homegrown privacy and security improvements, particularly low-level
|
||||
hardening work on the compiler toolchain and Bionic. Work began on landing code
|
||||
upstream in AOSP and other upstream projects. A substantial portion of these early
|
||||
changes were either successfully landed upstream or heavily influenced the upstream
|
||||
changes which replaced them. The project was able to move very quickly in these days
|
||||
because there was so much low hanging fruit to address and it wasn't yet trying to
|
||||
produce a highly robust, production quality OS.</p>
|
||||
|
||||
<p>In late 2015, a company was incorporated which became the primary sponsor of the
|
||||
project. GrapheneOS was <a href="/history/copperheados">previously known as
|
||||
CopperheadOS</a> while it was sponsored by this company. The intention was to use the
|
||||
company to build a business around GrapheneOS selling support, contract work and
|
||||
customized proprietary variants of the OS. The company was supposed to serve the needs
|
||||
of the open source project, rather than vice versa. It was explicitly agreed that
|
||||
GrapheneOS would remain independently owned and controlled by Daniel Micay. This
|
||||
company failed to live up the promises and is no longer associated in any way with
|
||||
GrapheneOS. The company ended up holding back the open source project and taking far
|
||||
more from it than was provided to it.</p>
|
||||
|
||||
<p>In 2018, the company was hijacked by the CEO who attempted to take over the project
|
||||
through coercion, but they were rebuked. They seized the infrastructure and stole the
|
||||
donations, but the project successfully moved on without them and has been fully
|
||||
revived. Since then, they've taken to fraudulently claiming ownership and authorship
|
||||
of our work, which has no basis in fact. They've tried to retroactively change the
|
||||
terms of their involvement and rewrite the history of the project. These claims are
|
||||
easily disproven through the public record and by people involved with the open source
|
||||
project and the former sponsor. This former sponsor has engaged in a campaign of
|
||||
misinformation and harassment of contributors to the project. Be aware that they are
|
||||
actively trying to sabotage GrapheneOS and are engaging in many forms of attacks
|
||||
against the project, the developers, contributors and supporters. Meanwhile, they
|
||||
continue profiting from our open source work which they falsely claim as their own
|
||||
creation.</p>
|
||||
|
||||
<p>After splitting from the former sponsor, the project was rebranded to
|
||||
AndroidHardening and then to GrapheneOS and it has continued down the original path of
|
||||
being an independent open source project. It will never again be closely tied to any
|
||||
particular sponsor or company.</p>
|
||||
|
||||
<p>GrapheneOS now has multiple full-time and part-time developers supported by
|
||||
donations and multiple companies collaborating with the project.</p>
|
||||
|
||||
<p>GrapheneOS Foundation was created as a non-profit organization in Canada in March
|
||||
2023 to handle the intake and distribution of donations.</p>
|
||||
|
||||
<section id="releases">
|
||||
<h2><a href="#releases">Releases</a></h2>
|
||||
|
||||
<p>A history of releases for the current incarnation of GrapheneOS is available
|
||||
via the <a href="/releases#changelog">releases changelog</a>.</p>
|
||||
|
||||
<p>An archive of changelogs for the earlier releases is available via the
|
||||
<a href="/history/legacy-changelog">legacy changelog page</a>.</p>
|
||||
</section>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
@ -1,60 +1,60 @@
|
||||
|
||||
|
||||
0N:
|
||||
0N:
|
||||
0N:
|
||||
0N:
|
||||
0N:
|
||||
0N:
|
||||
.;KNx,.
|
||||
.lKNNNNNNNO;
|
||||
.KNNNNNNNNNNNx
|
||||
xNNNNNNNNNNNNN,
|
||||
xNNNNNNNNNNNNN'
|
||||
.:ONNNNNNNNNNNNNd,
|
||||
dl' ,o0N0o,cONNNNNNXx;:xKXkc. .;oc
|
||||
.lONXx:. .ckXXk:. .';;,. 'l0NKd;. 'lONXx:
|
||||
.;o0NOl' 'okKXK0xc. .;dKXOl' .;dKNOl' 'okKXK0xc. .;dKXkl'
|
||||
.cOXX0NNNNNNNNNN0NKd;. .ckNX0NNNNNNNNNN0NXx;
|
||||
.XNNNNNNNNNNNNO .NNNNNNNNNNNNNk
|
||||
'NNNNNNNNNNNNNK 'NNNNNNNNNNNNNK
|
||||
KNNNNNNNNNNNNo KNNNNNNNNNNNNo
|
||||
.xNNNNNNNNNXc .xNNNNNNNNNXl
|
||||
.cxKNXOd; .cx0NNOd;
|
||||
dNx NN.
|
||||
dNx NN.
|
||||
dNx NN.
|
||||
dNx NN.
|
||||
dNx NN.
|
||||
dNx NN.
|
||||
dNx NN.
|
||||
dNx NN.
|
||||
'oOXNX0xc. 'oOKNNKkc.
|
||||
.ONNNNNNNNNXo .ONNNNNNNNNXo
|
||||
KNNNNNNNNNNNNd KNNNNNNNNNNNNd
|
||||
'NNNNNNNNNNNNNK 'NNNNNNNNNNNNNK
|
||||
.XNNNNNNNNNNNNO 'NNNNNNNNNNNNNO.
|
||||
'o0NKONNNNNNNNNXkXXkc. 'l0NKONNNNNNNNNXkXXOc.
|
||||
.:xXXx:. .cxO00kd; ,o0N0d;. .cxXXkc. .cxO00ko; 'lON0o;.
|
||||
.dKN0o, .;xKN0l. .;cc:,. ;dKN0o, .:xXNOl
|
||||
l:. .ckXKx:oKNNNNNNNO:lkXKd;. 'l:
|
||||
;kNNNNNNNNNNNNNl'
|
||||
xNNNNNNNNNNNNN,
|
||||
xNNNNNNNNNNNNN,
|
||||
.0NNNNNNNNNNNd
|
||||
cONNNNNNXx,
|
||||
.'KNd.
|
||||
0N:
|
||||
0N:
|
||||
0N:
|
||||
0N:
|
||||
0N:
|
||||
0N:
|
||||
..::::: . .
|
||||
-=*%@@@@@@@@#=:--
|
||||
:@@@@@@@@@@@@@@#-::
|
||||
.*%@@@@@@@@@@@@@@@@#=
|
||||
:-%@@@@@@@@@@@@@@@#
|
||||
=@@@@@@@@@@@@@@@%+ .:-=+=-.
|
||||
-+#@@@@@@@@@@@@@@@@@*-..-=======---=:
|
||||
:#@@@@@@@@@@@@@@@@@@@@@@@%+-: .:*@.
|
||||
*#@@@@@@@@@@@@@@@@@@@@@@@%*+%@**%%@%%@@@*-
|
||||
-@@@@@@@@@@@@@@@@@@@@@@@@@@%%@*-=+##%@=.-%%=.
|
||||
+@@@@@@@@@@@@@@@@@@@@@@@@@@#=@@*: :#@#: -%@*.
|
||||
:#@@@@@@@@@@@@@@@@@@@@@@@@@@@@#%%@@+ :@@- #@@*
|
||||
=@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%*@#-#@%. :@+:**%*:
|
||||
=@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#+@@@@@@..@#@=::.
|
||||
=%@#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@* #@@+-
|
||||
*@#*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%=-#@=
|
||||
=@@@%*#%@@@@@@@@@@@@@@@@@@@@@@#@@@==@@@: .%*
|
||||
.%@@@% %@@@@@@@@@@@@@@@@@@@@%%*-#%++@@+ .:=:
|
||||
*%@@@###@@@@@@@@@@@@@@@@@@@@%@#*%%*--
|
||||
.#-.#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%#**=-.
|
||||
%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%*-
|
||||
.#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#-
|
||||
.+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#+-:..:==
|
||||
:*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%#-
|
||||
.+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*
|
||||
=@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#.
|
||||
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
|
||||
.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
|
||||
.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@=
|
||||
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%
|
||||
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%+.
|
||||
*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%=
|
||||
.#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+=:
|
||||
+%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%#%@++##--=-.
|
||||
-%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#**
|
||||
.@@@@@@@@@@@@@@@@@@@@@@@@@@@%##
|
||||
...+@@@@@@@@@@@@@@@@@@@@@@@@@@@#
|
||||
.#@@@@@@@@@@@@@@@@@@@@@@@@@@@+--
|
||||
.=%@@@%##@@@@@@@@@@@@#*-=-..
|
||||
-: :*##@@@@@@@:
|
||||
*@@@@@@
|
||||
=@@@@@%
|
||||
.@@@@@+
|
||||
.@@@@@=
|
||||
:@@@@@=
|
||||
+@@@@@*
|
||||
.@@@@@@@-
|
||||
*@@@@@@@%
|
||||
.-==-==-
|
||||
|
||||
|
||||
|
||||
GrapheneOS is a collaboratively developed open source project.
|
||||
Hakurei is a collaboratively developed open source project.
|
||||
|
||||
See the repositories at https://github.com/GrapheneOS for more details.
|
||||
See the repositories at https://git.gensokyo.uk/security for more details.
|
||||
|
||||
This website is developed in the https://github.com/GrapheneOS/grapheneos.org repository.
|
||||
This website is developed in the https://git.gensokyo.uk/security/hakurei.app repository.
|
||||
|
@ -2,24 +2,24 @@
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>GrapheneOS: the private and secure mobile OS</title>
|
||||
<meta name="description" content="GrapheneOS is a security and privacy focused mobile OS with Android app compatibility."/>
|
||||
<title>Hakurei: the secure desktop application sandbox</title>
|
||||
<meta name="description" content="Hakurei is a security-focused Linux container runtime for desktop applications."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="GrapheneOS: the private and secure mobile OS"/>
|
||||
<meta property="og:description" content="GrapheneOS is a security and privacy focused mobile OS with Android app compatibility."/>
|
||||
<meta name="go-import" content="hakurei.app git https://git.gensokyo.uk/security/hakurei"/>
|
||||
<meta name="go-source" content="hakurei.app _ https://git.gensokyo.uk/security/hakurei/src/branch/master{/dir} https://git.gensokyo.uk/security/hakurei/src/branch/master{/dir}/{file}#L{line}"/>
|
||||
<meta property="og:title" content="Hakurei: the secure desktop application sandbox"/>
|
||||
<meta property="og:description" content="Hakurei is a security-focused Linux container runtime for desktop applications."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image" content="https://hakurei.app/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/"/>
|
||||
<meta property="og:image:alt" content="Hakurei logo"/>
|
||||
<meta property="og:site_name" content="Hakurei"/>
|
||||
<meta property="og:url" content="https://hakurei.app/"/>
|
||||
<link rel="canonical" href="https://hakurei.app/"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
@ -27,33 +27,32 @@
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
[[js|/js/redirect.js]]
|
||||
<link rel="me" href="https://port.mk/@hakurei"/>
|
||||
</head>
|
||||
<body>
|
||||
{% with current_page="/" %}
|
||||
{% include "header.html" %}
|
||||
{% endwith %}
|
||||
<main class="normalize" id="grapheneos">
|
||||
<main class="normalize" id="hakurei">
|
||||
<div class="content hero">
|
||||
|
||||
<div>
|
||||
<h1><a href="#grapheneos">GrapheneOS</a></h1>
|
||||
<p>The private and secure mobile operating system with Android app compatibility.
|
||||
<h1><a href="#hakurei">Hakurei</a></h1>
|
||||
<p>A security-focused Linux container runtime for desktop applications.
|
||||
Developed as a non-profit open source project.</p>
|
||||
<a class="button" href="/install/">Install GrapheneOS</a>
|
||||
<a class="button" href="/install.html">Install Hakurei</a>
|
||||
</div>
|
||||
|
||||
<figure class="device-img">
|
||||
<img class="phone-img" width="276" height="579" src="[[path|/pixel-7-pro.svg]]" alt=""/>
|
||||
<img class="phone-logo-img" width="200" height="200" src="[[path|/mask-icon.svg]]" alt=""/>
|
||||
<img class="laptop-img" width="288" height="171" src="[[path|/laptop.svg]]" alt=""/>
|
||||
<img class="laptop-logo-img" width="108" height="108" src="[[path|/mask-icon.svg]]" alt=""/>
|
||||
</figure>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="surface">
|
||||
<div class="content break">
|
||||
<p>Get to know GrapheneOS</p>
|
||||
<p>Get to know Hakurei</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -61,63 +60,59 @@
|
||||
<section id="about">
|
||||
<h2 class="start"><a href="#about">About</a></h2>
|
||||
|
||||
<p>GrapheneOS is a privacy and security focused mobile OS with Android app
|
||||
compatibility developed as a non-profit <a href="/source">open source</a>
|
||||
project. It's focused on the research and development of privacy and security
|
||||
technology including substantial improvements to sandboxing, exploit
|
||||
mitigations and the permission model. It was founded in 2014 and was
|
||||
<a href="/history/copperheados">formerly known as CopperheadOS</a>.</p>
|
||||
<p>Hakurei is a security-focused Linux container runtime for running unmodified
|
||||
desktop applications, developed as a non-profit <a
|
||||
href="https://git.gensokyo.uk/security/hakurei" target="_blank">open source</a>
|
||||
project. It also implements <a href="/package.html">planterette</a>, an
|
||||
experimental self-contained Android-like package manager with modern security
|
||||
features.</p>
|
||||
|
||||
<p>GrapheneOS improves the privacy and security of the OS from the bottom up.
|
||||
It deploys technologies to mitigate whole classes of vulnerabilities and make
|
||||
exploiting the most common sources of vulnerabilities substantially more
|
||||
difficult. It improves the security of both the OS and the apps running on it.
|
||||
The app sandbox and other security boundaries are fortified. GrapheneOS tries
|
||||
to avoid impacting the user experience with the privacy and security features.
|
||||
Ideally, the features can be designed so that they're always enabled with no
|
||||
impact on the user experience and no additional complexity like configuration
|
||||
options. It's not always feasible, and GrapheneOS does add various toggles for
|
||||
features like the Network permission, Sensors permission, restrictions when
|
||||
the device is locked (USB-C / pogo pins, camera, quick tiles), etc. along with
|
||||
more complex user-facing privacy and security features with their own UX.</p>
|
||||
<p>Security on the desktop has always left something to be desired. While <a
|
||||
href="https://www.qubes-os.org" target="_blank">Qubes OS</a> provides excellent
|
||||
security, its performance and usability limitations make it unsuitable for most
|
||||
use cases. Hakurei attempts to fill that gap by running applications natively
|
||||
while still establishing decent compartmentalisation enforced by the kernel.</p>
|
||||
|
||||
<p>The <a href="/features">features page</a> provides an overview of the
|
||||
substantial privacy and security improvements added by GrapheneOS to the
|
||||
Android Open Source Project (AOSP). Many of our past features were <a
|
||||
href="/faq#upstream">contributed to AOSP, Linux and other projects to improve
|
||||
privacy and security for billions of users</a> so they're no longer listed on
|
||||
our features page.</p>
|
||||
<p>Hakurei runs each container as a dedicated subordinate user and sets up the
|
||||
container via unprivileged user namespaces as another layer of defense against
|
||||
privilege escalation. Unprivileged user namespace creation is made unavailable
|
||||
in containers by default to reduce attack surface, but can be optionally enabled
|
||||
for applications with strong built-in sandboxes to avoid having to ruin their
|
||||
sandbox.</p>
|
||||
|
||||
<p>Official releases are available on the <a href="/releases">releases
|
||||
page</a> and installation instructions are on the <a href="/install/">install
|
||||
page</a>.</p>
|
||||
|
||||
<p>GrapheneOS also develops various apps and services with a focus on privacy
|
||||
and security. Vanadium is a hardened variant of the Chromium browser and
|
||||
WebView specifically built for GrapheneOS. GrapheneOS also includes our
|
||||
minimal security-focused PDF Viewer, our hardware-based Auditor app /
|
||||
attestation service providing local and remote verification of devices,
|
||||
our modern privacy / security focused camera app, and the externally developed
|
||||
Seedvault encrypted backup which was initially developed for inclusion in
|
||||
GrapheneOS.</p>
|
||||
<p>Official releases are available via <a
|
||||
href="https://git.gensokyo.uk/security/hakurei/releases" target="_blank">Gitea
|
||||
</a> and documentation for the included NixOS module can be found
|
||||
<a href="https://git.gensokyo.uk/security/hakurei/src/branch/master/options.md"
|
||||
target="_blank">here</a>.</p>
|
||||
</section>
|
||||
|
||||
<section id="never-google-services">
|
||||
<h2><a href="#never-google-services">No Google apps or services</a></h2>
|
||||
<section id="compatibility">
|
||||
<h2><a href="#compatibility">OS Compatibility</a></h2>
|
||||
|
||||
<p>GrapheneOS will never include either Google Play services or another
|
||||
implementation of Google services like microG. It's possible to install Play
|
||||
services as a set of fully sandboxed apps without special privileges via our
|
||||
<a href="/usage#sandboxed-google-play">sandboxed Google Play compatibility
|
||||
layer</a>. See <a href="/faq#google-services">the FAQ section</a> for more
|
||||
details on our plans for filling in the gaps from not shipping Play services
|
||||
and Google apps.</p>
|
||||
</section>
|
||||
<p>Hakurei does not try to support every major Linux distribution and their
|
||||
configuration of the kernel. Most Debian-based distributions disable
|
||||
unprivileged user namespace creation by default, and while that could be a
|
||||
good way to reduce attack surface, it also disables a layer of security
|
||||
where the kernel enforces strict limits on user namespaces created by
|
||||
an unprivileged user. Having to set up the sandbox as root also adds
|
||||
significant complexity to the setuid wrapper.
|
||||
The reduction of attack surface is also made irrelevant since hakurei can
|
||||
disable unprivileged user namespace creation on a per-container basis.</p>
|
||||
|
||||
<section id="device-support">
|
||||
<h2><a href="/faq#device-support">Device support</a></h2>
|
||||
<p>Users on affected kernels can switch to an unmodified (and up to date) kernel
|
||||
or enable unprivileged user namespace creation by setting the
|
||||
<code>kernel.unprivileged_userns_clone</code> sysctl to 1.
|
||||
Whether or not it increases attack surface is largely dependent on what runs
|
||||
on the system; however, if all apps are spawned by Hakurei and the rest of the
|
||||
system is sufficiently secured, enabling unprivileged user namespace creation
|
||||
should not increase attack surface whatsoever.</p>
|
||||
|
||||
<p class="end">See <a href="/faq#device-support">the FAQ section on device support</a>.</p>
|
||||
<p>While Hakurei is primarily developed on NixOS and relies on Nix for its
|
||||
integration test suite, it does not target NixOS or make assumptions that are
|
||||
only true on NixOS. Unfortunately, mistakes do happen semi-often as the
|
||||
architecture of NixOS can often hide bugs and assumptions. Please <a
|
||||
href="/contact.html">report</a> such anomalies if you encounter them.</p>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
|
50
static/install.html
Normal file
@ -0,0 +1,50 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Install | Hakurei</title>
|
||||
<meta name="description" content="Installation instructions for Hakurei, a security-focused Linux container runtime for desktop applications."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta property="og:title" content="Hakurei installation"/>
|
||||
<meta property="og:description" content="Installation instructions for Hakurei, a security-focused Linux container runtime for desktop applications."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://hakurei.app/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="Hakurei logo"/>
|
||||
<meta property="og:site_name" content="Hakurei"/>
|
||||
<meta property="og:url" content="https://hakurei.app/install.html"/>
|
||||
<link rel="canonical" href="https://hakurei.app/install.html"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://port.mk/@hakurei"/>
|
||||
</head>
|
||||
<body>
|
||||
{% with current_page="install" %}
|
||||
{% include "header.html" %}
|
||||
{% endwith %}
|
||||
<main id="install">
|
||||
<h1><a href="#install">Install</a></h1>
|
||||
|
||||
<p>Hakurei can be installed to almost any Linux-based operating system by running
|
||||
<code>install.sh</code> from a release tarball found <a
|
||||
href="https://git.gensokyo.uk/security/hakurei/releases" target="_blank">here</a>.
|
||||
With that said, the current easiest method for using Hakurei with desktop apps would be
|
||||
via the <a href="https://git.gensokyo.uk/security/hakurei/src/branch/master/options.md"
|
||||
target="_blank">companion NixOS module</a>.</p>
|
||||
|
||||
<p>We strongly recommend using one of the official installation methods. Third party
|
||||
installation guides tend to be out-of-date and often contain misguided advice and
|
||||
errors.</p>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
@ -1,666 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>CLI install guide | Install | GrapheneOS</title>
|
||||
<meta name="description" content="Command-line installation instructions for GrapheneOS, a security and privacy focused mobile OS with Android app compatibility."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="GrapheneOS CLI install guide"/>
|
||||
<meta property="og:description" content="Command-line installation instructions for GrapheneOS, a security and privacy focused mobile OS with Android app compatibility."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/install/cli"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/install/cli"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
[[js|/js/redirect.js]]
|
||||
</head>
|
||||
<body>
|
||||
{% include "header.html" %}
|
||||
<main id="cli-install">
|
||||
<h1><a href="#cli-install">CLI install guide</a></h1>
|
||||
|
||||
<p>This is a guide on installing GrapheneOS on the
|
||||
<a href="/faq#supported-devices">officially supported devices</a>. It can be followed
|
||||
for both the <a href="/releases">official releases</a> and <a href="/build">custom
|
||||
builds</a>. The <a href="/install/web">web installer</a> is an
|
||||
easier approach to installing the official releases via a browser with WebUSB
|
||||
support.</p>
|
||||
|
||||
<p>We strongly recommend following these official instructions. The official guide has
|
||||
a lot of collaborative effort put into covering all of the edge cases and is regularly
|
||||
tested by many people on each supported OS. Following these instructions to the letter
|
||||
without skipping, reordering or adding any steps will give you a proper GrapheneOS
|
||||
installation unless there's a hardware issue. We strongly recommend against following
|
||||
unofficial guides deviating in any way from the official instructions.</p>
|
||||
|
||||
<p>If you have trouble with the installation process, ask for help on the
|
||||
<a href="/contact#community">official GrapheneOS chat channel</a>. There are almost
|
||||
always people around willing to help with it. Before asking for help, make an attempt
|
||||
to follow the guide on your own and then ask for help with anything you get stuck
|
||||
on.</p>
|
||||
|
||||
<nav id="table-of-contents">
|
||||
<h2><a href="#table-of-contents">Table of contents</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#prerequisites">Prerequisites</a></li>
|
||||
<li><a href="#enabling-oem-unlocking">Enabling OEM unlocking</a></li>
|
||||
<li><a href="#opening-terminal">Opening terminal</a></li>
|
||||
<li>
|
||||
<a href="#obtaining-fastboot">Obtaining fastboot</a>
|
||||
<ul>
|
||||
<li><a href="#standalone-platform-tools">Standalone platform-tools</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#checking-fastboot-version">Checking fastboot version</a></li>
|
||||
<li><a href="#flashing-as-non-root">Flashing as non-root</a></li>
|
||||
<li><a href="#working-around-fwupd-bugs-on-linux-distributions">Working around fwupd bugs on Linux distributions</a></li>
|
||||
<li><a href="#booting-into-the-bootloader-interface">Booting into the bootloader interface</a></li>
|
||||
<li><a href="#connecting-device">Connecting the device</a></li>
|
||||
<li><a href="#unlocking-the-bootloader">Unlocking the bootloader</a></li>
|
||||
<li><a href="#obtaining-openssh">Obtaining OpenSSH</a></li>
|
||||
<li><a href="#obtaining-factory-images">Obtaining factory images</a></li>
|
||||
<li>
|
||||
<a href="#flashing-factory-images">Flashing factory images</a>
|
||||
<ul>
|
||||
<li><a href="#troubleshooting">Troubleshooting</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#locking-the-bootloader">Locking the bootloader</a></li>
|
||||
<li>
|
||||
<a href="#post-installation">Post-installation</a>
|
||||
<ul>
|
||||
<li><a href="#booting">Booting</a></li>
|
||||
<li><a href="#disabling-oem-unlocking">Disabling OEM unlocking</a></li>
|
||||
<li>
|
||||
<a href="#verifying-installation">Verifying installation</a>
|
||||
<ul>
|
||||
<li><a href="#verified-boot-key-hash">Verified boot key hash</a></li>
|
||||
<li><a href="#hardware-based-attestation">Hardware-based attestation</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#further-information">Further information</a></li>
|
||||
<li><a href="#replacing-grapheneos-with-the-stock-os">Replacing GrapheneOS with the stock OS</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<section id="prerequisites">
|
||||
<h2><a href="#prerequisites">Prerequisites</a></h2>
|
||||
|
||||
<p>You need a computer for running the CLI install process with at least 2GB of free
|
||||
memory available and 32GB of free storage space. The web installer can be run on an
|
||||
Android phone or tablet, unlike the command-line installation.</p>
|
||||
|
||||
<p>You need a USB cable for attaching the device to the computer performing the
|
||||
installation. Whenever possible, use the high quality standards compliant USB-C
|
||||
cable packaged with the device. If your computer doesn't have any USB-C ports,
|
||||
you'll need a high quality USB-C to USB-A cable. You should avoid using a USB hub
|
||||
such as the front panel on a desktop computer case. Connect directly to a rear port
|
||||
on a desktop or the ports on a laptop. Many widely distributed USB cables and hubs
|
||||
are broken and are the most common source of issues for installing GrapheneOS.</p>
|
||||
|
||||
<p>Installing from an OS in a virtual machine is not recommended. USB passthrough
|
||||
is often not reliable. To rule out these problems, install from an OS running on
|
||||
bare metal. Virtual machines are also often configured to have overly limited
|
||||
memory and storage space.</p>
|
||||
|
||||
<p>Officially supported operating systems for the CLI install method:</p>
|
||||
|
||||
<ul>
|
||||
<li>Windows 10</li>
|
||||
<li>Windows 11</li>
|
||||
<li>macOS Ventura (13)</li>
|
||||
<li>macOS Sonoma (14)</li>
|
||||
<li>macOS Sequoia (15)</li>
|
||||
<li>Arch Linux</li>
|
||||
<li>Debian 11 (bullseye)</li>
|
||||
<li>Debian 12 (bookworm)</li>
|
||||
<li>Ubuntu 20.04 LTS</li>
|
||||
<li>Ubuntu 22.04 LTS</li>
|
||||
<li>Ubuntu 24.04 LTS</li>
|
||||
<li>Ubuntu 24.10</li>
|
||||
<li>Linux Mint 20 (follow Ubuntu 20.04 LTS instructions)</li>
|
||||
<li>Linux Mint 21 (follow Ubuntu 22.04 LTS instructions)</li>
|
||||
<li>Linux Mint 22 (follow Ubuntu 24.04 LTS instructions)</li>
|
||||
<li>Linux Mint Debian Edition 6 (follow Debian 12 instructions)</li>
|
||||
</ul>
|
||||
|
||||
<p>Make sure your operating system is up-to-date before proceeding.</p>
|
||||
|
||||
<p>The <a href="/install/web">web installer</a> is more portable and can be used
|
||||
from Android, ChromeOS and GrapheneOS itself since it can run anywhere with a
|
||||
browser with working WebUSB support.</p>
|
||||
|
||||
<p>You need one of the <a href="/faq#supported-devices">officially supported
|
||||
devices</a>. To make sure that the device can be unlocked to install GrapheneOS,
|
||||
avoid carrier variants of the devices. Carrier variants of Pixels use the same stock
|
||||
OS and firmware with a non-zero carrier id flashed onto the persist partition in the
|
||||
factory. The carrier id activates carrier-specific configuration in the stock OS
|
||||
including disabling carrier and bootloader unlocking. The carrier may be able to
|
||||
remotely disable this, but their support staff may not be aware and they probably
|
||||
won't do it. Get a carrier agnostic device to avoid the risk and potential hassle.
|
||||
If you CAN figure out a way to unlock a carrier device, it isn't a problem as
|
||||
GrapheneOS can just ignore the carrier id and the hardware is the same.</p>
|
||||
|
||||
<p>It's best practice to update the device before installing GrapheneOS to have
|
||||
the latest firmware for connecting the device to the computer and performing the
|
||||
early flashing process. Either way, GrapheneOS flashes the latest firmware early
|
||||
in the installation process.</p>
|
||||
</section>
|
||||
|
||||
<section id="enabling-oem-unlocking">
|
||||
<h2><a href="#enabling-oem-unlocking">Enabling OEM unlocking</a></h2>
|
||||
|
||||
<p>OEM unlocking needs to be enabled from within the operating system.</p>
|
||||
|
||||
<p>Enable the developer options menu by going to <b>Settings <span
|
||||
aria-label="and then">></span> About phone/tablet</b> and repeatedly
|
||||
pressing the <b>Build number</b> menu entry until developer mode is enabled.</p>
|
||||
|
||||
<p>Next, go to <b>Settings <span aria-label="and then">></span>
|
||||
System <span aria-label="and then">></span> Developer options</b> and
|
||||
toggle on the <b>OEM unlocking</b> setting. On device model variants (SKUs) which
|
||||
support being sold as locked devices by carriers, enabling <b>OEM unlocking</b>
|
||||
requires internet access so that the stock OS can check if the device was sold as
|
||||
locked by a carrier.</p>
|
||||
|
||||
<p>For the Pixel 6a, OEM unlocking won't work with the version of the stock OS
|
||||
from the factory. You need to update it to the June 2022 release or later via an
|
||||
over-the-air update. After you've updated it you'll also need to factory reset
|
||||
the device to fix OEM unlocking.</p>
|
||||
</section>
|
||||
|
||||
<section id="opening-terminal">
|
||||
<h2><a href="#opening-terminal">Opening terminal</a></h2>
|
||||
|
||||
<p>These instructions use command-line tools. Launch the terminal as you would any
|
||||
other application. On Windows, launch a regular non-administrator instance of the
|
||||
PowerShell terminal. Do not use the legacy Command Prompt or administrator variant
|
||||
of PowerShell.</p>
|
||||
|
||||
<p>Use the same terminal for the whole installation process. If you close it,
|
||||
you'll lose the setup of the environment for the installation.</p>
|
||||
|
||||
<p>On Windows, run the following command to remove PowerShell's legacy curl alias
|
||||
for the current shell to avoid needing to reference it as <code>curl.exe</code>
|
||||
instead of <code>curl</code>:</p>
|
||||
|
||||
<pre>Remove-Item Alias:Curl</pre>
|
||||
</section>
|
||||
|
||||
<section id="obtaining-fastboot">
|
||||
<h2><a href="#obtaining-fastboot">Obtaining fastboot</a></h2>
|
||||
|
||||
<p>You need an updated copy of the <code>fastboot</code> tool and the
|
||||
directory containing it needs to be included in the <code>PATH</code>
|
||||
environment variable. You can run <code>fastboot --version</code> to determine
|
||||
the current version. It must be at least <code>35.0.1</code>. You can use a
|
||||
distribution package for this, but most of them mistakenly package development
|
||||
snapshots of fastboot, clobber the standard version scheme for platform-tools
|
||||
(adb, fastboot, etc.) with their own scheme and don't keep it up-to-date
|
||||
despite that being crucial.</p>
|
||||
|
||||
<p>On Arch Linux, install <code>android-tools</code> and skip the section below on
|
||||
using the standalone release of platform-tools from Android:</p>
|
||||
|
||||
<pre>sudo pacman -S android-tools</pre>
|
||||
|
||||
<p>Debian and Ubuntu do not have a usable package for fastboot. Their packages for
|
||||
these tools are both broken and many years out-of-date. Follow the instructions
|
||||
below for platforms without a proper package.</p>
|
||||
|
||||
<section id="standalone-platform-tools">
|
||||
<h3><a href="#standalone-platform-tools">Standalone platform-tools</a></h3>
|
||||
|
||||
<!-- https://developer.android.com/studio/releases/platform-tools -->
|
||||
|
||||
<p>If your operating system doesn't include a usable version of fastboot,
|
||||
you can use the official standalone releases of platform-tools. This is
|
||||
our recommendation for most users. The flashing process won't work unless
|
||||
you follow these instructions including setting up PATH.</p>
|
||||
|
||||
<p>To download, verify and extract the standalone platform-tools on Debian and
|
||||
Ubuntu:</p>
|
||||
|
||||
<pre>sudo apt install libarchive-tools
|
||||
curl -O https://dl.google.com/android/repository/platform-tools_r35.0.2-linux.zip
|
||||
echo 'acfdcccb123a8718c46c46c059b2f621140194e5ec1ac9d81715be3d6ab6cd0a platform-tools_r35.0.2-linux.zip' | sha256sum -c
|
||||
bsdtar xvf platform-tools_r35.0.2-linux.zip</pre>
|
||||
|
||||
<p>To download, verify and extract the standalone platform-tools on macOS:</p>
|
||||
|
||||
<pre>curl -O https://dl.google.com/android/repository/platform-tools_r35.0.2-darwin.zip
|
||||
echo 'SHA256 (platform-tools_r35.0.2-darwin.zip) = 1820078db90bf21628d257ff052528af1c61bb48f754b3555648f5652fa35d78' | shasum -c
|
||||
tar xvf platform-tools_r35.0.2-darwin.zip</pre>
|
||||
|
||||
<p>To download, verify and extract the standalone platform-tools on Windows:</p>
|
||||
|
||||
<pre>curl -O https://dl.google.com/android/repository/platform-tools_r35.0.2-win.zip
|
||||
(Get-FileHash platform-tools_r35.0.2-win.zip).hash -eq "2975a3eac0b19182748d64195375ad056986561d994fffbdc64332a516300bb9"
|
||||
tar xvf platform-tools_r35.0.2-win.zip</pre>
|
||||
|
||||
<p>Next, add the tools to your <code>PATH</code> in the current shell so they can be
|
||||
used without referencing them by file path, enabling usage by the flashing script.</p>
|
||||
|
||||
<p>On Debian, Ubuntu and macOS:</p>
|
||||
|
||||
<pre>export PATH="$PWD/platform-tools:$PATH"</pre>
|
||||
|
||||
<p>On Windows:</p>
|
||||
|
||||
<pre>$env:Path = "$pwd\platform-tools;$env:Path"</pre>
|
||||
|
||||
<p>This only changes <code>PATH</code> for the current shell and will need
|
||||
to be done again if you open a new terminal.</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="checking-fastboot-version">
|
||||
<h2><a href="#checking-fastboot-version">Checking fastboot version</a></h2>
|
||||
|
||||
<p>Check the output of <code>fastboot --version</code> before continuing.</p>
|
||||
|
||||
<p>Example of the output after following the instructions above for the
|
||||
standalone platform-tools:</p>
|
||||
|
||||
<pre>fastboot version 35.0.2-12147458
|
||||
Installed as /home/username/platform-tools/fastboot</pre>
|
||||
</section>
|
||||
|
||||
<section id="flashing-as-non-root">
|
||||
<h2><a href="#flashing-as-non-root">Flashing as non-root</a></h2>
|
||||
|
||||
<p>On traditional Linux distributions, USB devices cannot be used as non-root
|
||||
without udev rules for each type of device. This is not an issue for other
|
||||
platforms.</p>
|
||||
|
||||
<p>On Arch Linux:</p>
|
||||
|
||||
<pre>sudo pacman -S android-udev</pre>
|
||||
|
||||
<p>On Debian and Ubuntu:</p>
|
||||
|
||||
<pre>sudo apt install android-sdk-platform-tools-common</pre>
|
||||
|
||||
<p>The udev rules on Debian and Ubuntu are very out-of-date but the package has
|
||||
the rules needed for Pixel devices since the same USB IDs have been used for many
|
||||
years.</p>
|
||||
</section>
|
||||
|
||||
<section id="working-around-fwupd-bugs-on-linux-distributions">
|
||||
<h2><a href="#working-around-fwupd-bugs-on-linux-distributions">Working around fwupd bugs on Linux distributions</a></h2>
|
||||
|
||||
<p>The fwupd software often used on Linux distributions for updating firmware is
|
||||
known to incorrectly connect to arbitrary devices using the fastboot protocol which
|
||||
will block using them for the intended purpose. This can result in receiving an
|
||||
error about the USB device already being in use (claimed) when trying to connect to
|
||||
it for the intended purpose.</p>
|
||||
|
||||
<p>You can stop fwupd with the following command:</p>
|
||||
|
||||
<pre>sudo systemctl stop fwupd.service</pre>
|
||||
|
||||
<p>This doesn't disable the service and it will start again on reboot.</p>
|
||||
</section>
|
||||
|
||||
<section id="booting-into-the-bootloader-interface">
|
||||
<h2><a href="#booting-into-the-bootloader-interface">Booting into the bootloader interface</a></h2>
|
||||
|
||||
<p>You need to boot your device into the bootloader interface. To do this, you need
|
||||
to hold the volume down button while the device boots.</p>
|
||||
|
||||
<p>The easiest approach is to reboot the device and begin holding the volume down
|
||||
button until it boots up into the bootloader interface.</p>
|
||||
|
||||
<p>Alternatively, turn off the device, then boot it up while holding the volume
|
||||
down button during the boot process. You can either boot it with the power button
|
||||
or by plugging it in as required in the next section.</p>
|
||||
|
||||
<p>This step is not complete until your device displays a red warning triangle
|
||||
and the words "Fastboot Mode". You must not press the device's power button
|
||||
to activate the "Start" menu item, because the device must remain paused in
|
||||
Fastboot mode for the <code>fastboot</code> command to connect to it.</p>
|
||||
</section>
|
||||
|
||||
<section id="connecting-device">
|
||||
<h2><a href="#connecting-device">Connecting the device</a></h2>
|
||||
|
||||
<p>Connect the device to the computer. On Linux, you'll need to do this again if
|
||||
you didn't have the udev rules set up when you connected it.</p>
|
||||
|
||||
<p>Current Windows 10 and Windows 11 include a generic driver usable for fastboot
|
||||
and no longer require installing a driver for installation on the Pixel 4a (5G) or
|
||||
later. It isn't enough for legacy 4th generation Pixels due to the driver not
|
||||
handling fastbootd, so you still need the driver for those. Outdated Windows
|
||||
versions will still need the driver for non-obsolete devices too. You can obtain the
|
||||
driver from Windows Update which will detect it as an optional update when the
|
||||
device is booted into the bootloader interface and connected to the computer. Open
|
||||
Windows Update, run a check for updates and then open the "View optional updates"
|
||||
interface. Install the driver for the Android bootloader interface as an optional
|
||||
update, which will show up as "LeMobile Android Device" due to USB ID overlap. An
|
||||
alternative approach to obtaining the Windows fastboot driver is to obtain the <a
|
||||
href="https://developer.android.com/studio/run/win-usb">latest driver for
|
||||
Pixels</a> from Google and then <a href="https://developer.android.com/studio/run/oem-usb#InstallingDriver">manually
|
||||
install it with the Windows Device Manager</a>.</p>
|
||||
|
||||
<p>For the Pixel Tablet, disconnect it from the stand before continuing. The stand
|
||||
uses USB to provide charging and audio output, but the tablet lacks support for
|
||||
using both the stand and USB port at the same time.</p>
|
||||
</section>
|
||||
|
||||
<section id="unlocking-the-bootloader">
|
||||
<h2><a href="#unlocking-the-bootloader">Unlocking the bootloader</a></h2>
|
||||
|
||||
<p>Unlock the bootloader to allow flashing the OS and firmware:</p>
|
||||
|
||||
<pre>fastboot flashing unlock</pre>
|
||||
|
||||
<p>The command needs to be confirmed on the device and will wipe all data. Use one
|
||||
of the volume buttons to switch the selection to accepting it and the power button
|
||||
to confirm.</p>
|
||||
</section>
|
||||
|
||||
<section id="obtaining-openssh">
|
||||
<h2><a href="#obtaining-openssh">Obtaining openssh</a></h2>
|
||||
|
||||
<p>OpenSSH is used to verify the download of the OS beyond the security offered by
|
||||
HTTPS.</p>
|
||||
|
||||
<p>macOS and Windows include OpenSSH in their base install so this isn't needed.</p>
|
||||
|
||||
<p>On Arch Linux:</p>
|
||||
|
||||
<pre>sudo pacman -S openssh</pre>
|
||||
|
||||
<p>On Debian and Ubuntu:</p>
|
||||
|
||||
<pre>sudo apt install openssh-client</pre>
|
||||
</section>
|
||||
|
||||
<section id="obtaining-factory-images">
|
||||
<h2><a href="#obtaining-factory-images">Obtaining factory images</a></h2>
|
||||
|
||||
<p>You need to obtain the GrapheneOS factory images for your device to proceed with
|
||||
the installation process.</p>
|
||||
|
||||
<p>You can either download the files with your browser or using a command like
|
||||
<code>curl</code>. It's generally easier to use the command-line since you're already
|
||||
using it for the rest of the installation process, so these instructions use
|
||||
<code>curl</code>.</p>
|
||||
|
||||
<p>Download <a href="https://releases.grapheneos.org/allowed_signers">the factory images
|
||||
public key (allowed_signers)</a> in order to verify the factory images:</p>
|
||||
|
||||
<pre>curl -O https://releases.grapheneos.org/allowed_signers</pre>
|
||||
|
||||
<p>This is the content of <code>allowed_signers</code>:</p>
|
||||
|
||||
<pre>contact@grapheneos.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIUg/m5CoP83b0rfSCzYSVA4cw4ir49io5GPoxbgxdJE</pre>
|
||||
|
||||
<p>Other locations to obtain the signing key:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://bsky.app/profile/grapheneos.org/post/3kleyygkptm2x">Bluesky</a></li>
|
||||
<li><a href="https://x.com/GrapheneOS/status/1757758688952009209">Twitter</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/releases.grapheneos.org/blob/main/static/allowed_signers">GitHub</a></li>
|
||||
</ul>
|
||||
|
||||
<p>When the current signing key is replaced, the new key will be signed with it.</p>
|
||||
|
||||
<p>Download the factory images for the device from <a href="/releases">the releases
|
||||
page</a>. For example, to download the <code><var>VERSION</var></code> release for
|
||||
a device with the codename <code><var>DEVICE_NAME</var></code>:</p>
|
||||
|
||||
<pre>curl -O https://releases.grapheneos.org/<var>DEVICE_NAME</var>-install-<var>VERSION</var>.zip
|
||||
curl -O https://releases.grapheneos.org/<var>DEVICE_NAME</var>-install-<var>VERSION</var>.zip.sig</pre>
|
||||
|
||||
<p>Next, verify the factory images using the signature.</p>
|
||||
|
||||
<p>On Linux and macOS:</p>
|
||||
|
||||
<pre>ssh-keygen -Y verify -f allowed_signers -I contact@grapheneos.org -n "factory images" -s <var>DEVICE_NAME</var>-install-<var>VERSION</var>.zip.sig < <var>DEVICE_NAME</var>-install-<var>VERSION</var>.zip</pre>
|
||||
|
||||
<p>On Windows:</p>
|
||||
|
||||
<pre>cmd /c 'ssh-keygen -Y verify -f allowed_signers -I contact@grapheneos.org -n "factory images" -s <var>DEVICE_NAME</var>-install-<var>VERSION</var>.zip.sig < <var>DEVICE_NAME</var>-install-<var>VERSION</var>.zip'</pre>
|
||||
|
||||
<p>This will produce the following output when successful:</p>
|
||||
|
||||
<pre>Good "factory images" signature for contact@grapheneos.org with ED25519 key SHA256:AhgHif0mei+9aNyKLfMZBh2yptHdw/aN7Tlh/j2eFwM</pre>
|
||||
</section>
|
||||
|
||||
<section id="flashing-factory-images">
|
||||
<h2><a href="#flashing-factory-images">Flashing factory images</a></h2>
|
||||
|
||||
<p>The initial install will be performed by flashing the factory images. This will
|
||||
replace the existing OS installation and wipe all the existing data.</p>
|
||||
|
||||
<p>Next, extract the factory images.</p>
|
||||
|
||||
<p>On Linux:</p>
|
||||
|
||||
<pre>bsdtar xvf <var>DEVICE_NAME</var>-install-<var>VERSION</var>.zip</pre>
|
||||
|
||||
<p>On macOS and Windows:</p>
|
||||
|
||||
<pre>tar xvf <var>DEVICE_NAME</var>-install-<var>VERSION</var>.zip</pre>
|
||||
|
||||
<p>Move into the directory:</p>
|
||||
|
||||
<pre>cd <var>DEVICE_NAME</var>-install-<var>VERSION</var></pre>
|
||||
|
||||
<p>Flash the images with the flash-all script in the directory.</p>
|
||||
|
||||
<p>On Linux and macOS:</p>
|
||||
|
||||
<pre>bash flash-all.sh</pre>
|
||||
|
||||
<p>On Windows:</p>
|
||||
|
||||
<pre>./flash-all.bat</pre>
|
||||
|
||||
<p>Wait for the flashing process to complete. It will automatically handle
|
||||
flashing the firmware, rebooting into the bootloader interface and flashing the OS.
|
||||
Avoid interacting with the device until the flashing script is finished. Then,
|
||||
proceed to <a href="#locking-the-bootloader">locking the bootloader</a> before using
|
||||
the device as locking wipes the data again.</p>
|
||||
|
||||
<section id="troubleshooting">
|
||||
<h3><a href="#troubleshooting">Troubleshooting</a></h3>
|
||||
|
||||
<p>The text output from a failed attempt at flashing will contain valuable
|
||||
diagnostic information which is essential in knowing where and how the process
|
||||
went wrong. Please provide this information when asking for help on the
|
||||
<a href="/contact#community">GrapheneOS chat room</a>.</p>
|
||||
|
||||
<p>A common issue on Linux distributions is that they mount the default temporary file
|
||||
directory <code>/tmp</code> as tmpfs which results in it being backed by memory and
|
||||
swap rather than persistent storage. By default, the size is 50% of the available
|
||||
virtual memory. This is often not enough for the flashing process, especially since
|
||||
<code>/tmp</code> is shared between applications and users. To use a different
|
||||
temporary directory if your <code>/tmp</code> doesn't have enough space available:</p>
|
||||
|
||||
<pre>mkdir tmp && TMPDIR="$PWD/tmp" ./flash-all.sh</pre>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="locking-the-bootloader">
|
||||
<h2><a href="#locking-the-bootloader">Locking the bootloader</a></h2>
|
||||
|
||||
<p>Locking the bootloader is important as it enables full verified boot. It also
|
||||
prevents using fastboot to flash, format or erase partitions. Verified boot will
|
||||
detect modifications to any of the OS partitions and it will prevent reading any
|
||||
modified / corrupted data. If changes are detected, error correction data is used
|
||||
to attempt to obtain the original data at which point it's verified again which
|
||||
makes verified boot robust to non-malicious corruption.</p>
|
||||
|
||||
<p>In the bootloader interface, set it to locked:</p>
|
||||
|
||||
<pre>fastboot flashing lock</pre>
|
||||
|
||||
<p>The command needs to be confirmed on the device and will wipe all data. Use one
|
||||
of the volume buttons to switch the selection to accepting it and the power button
|
||||
to confirm.</p>
|
||||
</section>
|
||||
|
||||
<section id="post-installation">
|
||||
<h2><a href="#post-installation">Post-installation</a></h2>
|
||||
|
||||
<section id="booting">
|
||||
<h3><a href="#booting">Booting</a></h3>
|
||||
|
||||
<p>You've now successfully installed GrapheneOS and can boot it. Pressing the
|
||||
power button with the default Start option selected in the bootloader
|
||||
interface will boot the OS.</p>
|
||||
</section>
|
||||
|
||||
<section id="disabling-oem-unlocking">
|
||||
<h3><a href="#disabling-oem-unlocking">Disabling OEM unlocking</a></h3>
|
||||
|
||||
<p>During first setup, the final screen will contain a toggle regarding OEM
|
||||
unlocking which is checked by default. This will disable OEM unlocking, which is
|
||||
recommended.</p>
|
||||
|
||||
<p>If you need to enable or disable OEM unlocking in the future, it can be done
|
||||
in the developer settings menu within the operating system.</p>
|
||||
</section>
|
||||
|
||||
<section id="verifying-installation">
|
||||
<h3><a href="#verifying-installation">Verifying installation</a></h3>
|
||||
|
||||
<p>The verified boot and attestation features provided by the supported
|
||||
devices can be used to verify that the hardware, firmware and GrapheneOS
|
||||
installation are genuine. Even if the computer you used to flash GrapheneOS
|
||||
was compromised and an attacker replaced GrapheneOS with their own malicious
|
||||
OS, it can be detected with these features.</p>
|
||||
|
||||
<p>Verified boot verifies the entirety of the firmware and OS images on every
|
||||
boot. The public key for the firmware images is burned into fuses in the SoC at
|
||||
the factory. Firmware security updates also update the rollback index burned
|
||||
into fuses to provide rollback protection.</p>
|
||||
|
||||
<p>The final firmware boot stage before the OS is responsible for verifying
|
||||
it. For the stock OS, it uses a hard-wired public key. Installing GrapheneOS
|
||||
flashes the GrapheneOS verified boot public key to the secure element. Each
|
||||
boot, this key is loaded and used to verify the OS. For both the stock OS and
|
||||
GrapheneOS, a rollback index based on the security patch level is loaded from
|
||||
the secure element to provide rollback protection.</p>
|
||||
|
||||
<section id="verified-boot-key-hash">
|
||||
<h3><a href="#verified-boot-key-hash">Verified boot key hash</a></h3>
|
||||
|
||||
<p>When loading an alternate OS, the device shows a yellow notice on boot
|
||||
with the ID of the alternate OS based on the sha256 of the verified boot
|
||||
public key. 4th and 5th generation Pixels only show the first 32 bits of
|
||||
the hash so you can't use this approach. 6th generation Pixels onwards
|
||||
show the full hash and you can compare it against the official GrapheneOS
|
||||
verified boot key hashes below:</p>
|
||||
|
||||
<ul>
|
||||
<li>Pixel 9a: <code>0508de44ee00bfb49ece32c418af1896391abde0f05b64f41bc9a2dfb589445b</code></li>
|
||||
<li>Pixel 9 Pro Fold: <code>af4d2c6e62be0fec54f0271b9776ff061dd8392d9f51cf6ab1551d346679e24c</code></li>
|
||||
<li>Pixel 9 Pro XL: <code>55d3c2323db91bb91f20d38d015e85112d038f6b6b5738fe352c1a80dba57023</code></li>
|
||||
<li>Pixel 9 Pro: <code>f729cab861da1b83fdfab402fc9480758f2ae78ee0b61c1f2137dd1ab7076e86</code></li>
|
||||
<li>Pixel 9: <code>9e6a8f3e0d761a780179f93acd5721ba1ab7c8c537c7761073c0a754b0e932de</code></li>
|
||||
<li>Pixel 8a: <code>096b8bd6d44527a24ac1564b308839f67e78202185cbff9cfdcb10e63250bc5e</code></li>
|
||||
<li>Pixel 8 Pro: <code>896db2d09d84e1d6bb747002b8a114950b946e5825772a9d48ba7eb01d118c1c</code></li>
|
||||
<li>Pixel 8: <code>cd7479653aa88208f9f03034810ef9b7b0af8a9d41e2000e458ac403a2acb233</code></li>
|
||||
<li>Pixel Fold: <code>ee0c9dfef6f55a878538b0dbf7e78e3bc3f1a13c8c44839b095fe26dd5fe2842</code></li>
|
||||
<li>Pixel Tablet: <code>94df136e6c6aa08dc26580af46f36419b5f9baf46039db076f5295b91aaff230</code></li>
|
||||
<li>Pixel 7a: <code>508d75dea10c5cbc3e7632260fc0b59f6055a8a49dd84e693b6d8899edbb01e4</code></li>
|
||||
<li>Pixel 7 Pro: <code>bc1c0dd95664604382bb888412026422742eb333071ea0b2d19036217d49182f</code></li>
|
||||
<li>Pixel 7: <code>3efe5392be3ac38afb894d13de639e521675e62571a8a9b3ef9fc8c44fd17fa1</code></li>
|
||||
<li>Pixel 6a: <code>08c860350a9600692d10c8512f7b8e80707757468e8fbfeea2a870c0a83d6031</code></li>
|
||||
<li>Pixel 6 Pro: <code>439b76524d94c40652ce1bf0d8243773c634d2f99ba3160d8d02aa5e29ff925c</code></li>
|
||||
<li>Pixel 6: <code>f0a890375d1405e62ebfd87e8d3f475f948ef031bbf9ddd516d5f600a23677e8</code></li>
|
||||
</ul>
|
||||
|
||||
<p>Checking this is useful after installation, but you don't need to check
|
||||
it manually for verified boot to work. The verified boot public key
|
||||
flashed to the secure element can only be changed when the device is
|
||||
unlocked. Unlocking the device performs the same wiping of the secure
|
||||
element as a factory reset and prevents data from being recovered even if
|
||||
the SSD was cloned and your passphrase(s) are obtained because the
|
||||
encryption keys can no longer be derived anymore. The verified boot key is
|
||||
also one of the inputs for deriving the encryption keys in addition to the
|
||||
user's lock method(s) and random token(s) on the secure element.</p>
|
||||
</section>
|
||||
|
||||
<section id="hardware-based-attestation">
|
||||
<h3><a href="#hardware-based-attestation">Hardware-based attestation</a></h3>
|
||||
|
||||
<p>GrapheneOS provides our Auditor app for using a combination of the
|
||||
verified boot and attestation features to verify that the hardware,
|
||||
firmware and operating system are genuine along with providing other
|
||||
useful data from the hardware and operating system.</p>
|
||||
|
||||
<p>Since the purpose of Auditor is to obtain information about the device
|
||||
without trusting it to be honest, results aren't shown on the device being
|
||||
verified. You need a 2nd Android device running Auditor for local QR code
|
||||
based verification. You can also use our optional device integrity
|
||||
monitoring service for automatic scheduled verifications with support for
|
||||
email alerts.</p>
|
||||
|
||||
<p>See the <a href="https://attestation.app/tutorial">Auditor tutorial</a>
|
||||
for a guide.</p>
|
||||
|
||||
<p>Auditor is primarily based on a pairing model where it generates a
|
||||
hardware backed signing key and hardware backed attestation signing key
|
||||
and pins them as part of the initial verification. The first verification
|
||||
is bootstrapped based on chaining trust to one of the Android attestation
|
||||
roots. After the first verification, it provides a highly secure system
|
||||
for obtaining information about the device going forward. An attacker
|
||||
could bypass the initial verification with a leaked attestation key or by
|
||||
proxying to another device with the device model, OS and patch level that
|
||||
the user is expecting. Proxying to another device will be addressed in the
|
||||
future with optional support for the hardware serial number attestation
|
||||
feature.</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="further-information">
|
||||
<h3><a href="#further-information">Further information</a></h3>
|
||||
|
||||
<p>Please look through the <a href="/usage">usage guide</a> and
|
||||
<a href="/faq">FAQ</a> for more information. If you have further questions not
|
||||
covered by the site, join the <a href="/contact#community">official GrapheneOS
|
||||
chat channels</a> and ask the questions in the appropriate channel.</p>
|
||||
</section>
|
||||
|
||||
<section id="replacing-grapheneos-with-the-stock-os">
|
||||
<h3><a href="#replacing-grapheneos-with-the-stock-os">Replacing GrapheneOS with the stock OS</a></h3>
|
||||
|
||||
<p>Installation of the stock OS via the stock factory images is the same process
|
||||
described above. However, before flashing and locking, there's an additional step
|
||||
to fully revert the device to a clean factory state.</p>
|
||||
|
||||
<p>The GrapheneOS factory images flash a non-stock Android Verified Boot key which
|
||||
needs to be erased to fully revert back to a stock device state. Before flashing the
|
||||
stock factory images, you should boot the device into fastboot mode and make sure the
|
||||
bootloader is unlocked. Then erase the custom Android Verified Boot key to untrust it:</p>
|
||||
|
||||
<pre>fastboot erase avb_custom_key</pre>
|
||||
</section>
|
||||
</section>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
@ -1,63 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Install | GrapheneOS</title>
|
||||
<meta name="description" content="Installation instructions for GrapheneOS, a security and privacy focused mobile OS with Android app compatibility."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="GrapheneOS installation"/>
|
||||
<meta property="og:description" content="Installation instructions for GrapheneOS, a security and privacy focused mobile OS with Android app compatibility."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/install/"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/install/"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
[[js|/js/redirect.js]]
|
||||
</head>
|
||||
<body>
|
||||
{% with current_page="install" %}
|
||||
{% include "header.html" %}
|
||||
{% endwith %}
|
||||
<main id="install">
|
||||
<h1><a href="#install">Install</a></h1>
|
||||
|
||||
<p>GrapheneOS has two officially supported installation methods. You can either use
|
||||
the <a href="/install/web">WebUSB-based installer</a> recommended for most users or
|
||||
the <a href="/install/cli">command-line installation guide</a> aimed at more technical
|
||||
users.</p>
|
||||
|
||||
<p>We strongly recommend using one of the official installation methods. Third party
|
||||
installation guides tend to be out-of-date and often contain misguided advice and
|
||||
errors.</p>
|
||||
|
||||
<p>If you have trouble with the installation process, ask for help on the
|
||||
<a href="/contact#community">official GrapheneOS chat channel</a>. There are almost
|
||||
always people around willing to help with it. Before asking for help, make an attempt
|
||||
to follow the guide on your own and then ask for help with anything you get stuck
|
||||
on.</p>
|
||||
|
||||
<p>The command-line approach requires being on an OS with proper fastboot and OpenSSH
|
||||
packages, along with understanding the process enough to avoid blindly trusting the
|
||||
instructions from our site. The web-based installation approach avoids needing any
|
||||
software beyond a browser with WebUSB support and you can still avoid trusting our
|
||||
server infrastructure by checking the verified boot key hash.</p>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
@ -1,489 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Web installer | Install | GrapheneOS</title>
|
||||
<meta name="description" content="Web-based installer for GrapheneOS, a security and privacy focused mobile OS with Android app compatibility."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="GrapheneOS web installer"/>
|
||||
<meta property="og:description" content="Web-based installer for GrapheneOS, a security and privacy focused mobile OS with Android app compatibility."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/install/web"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/install/web"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
[[js|/js/redirect.js]]
|
||||
<script type="module" src="/js/fastboot/ffe7e270/fastboot.min.mjs" integrity="sha256-/TM74wkIOUV1rXRSGlzJPb4ZjBA52fzUW3aSypxxtwc="></script>
|
||||
[[js|/js/web-install.js]]
|
||||
</head>
|
||||
<body>
|
||||
{% include "header.html" %}
|
||||
<main id="web-install">
|
||||
<h1><a href="#web-install">Web installer</a></h1>
|
||||
|
||||
<p>This is the WebUSB-based installer for GrapheneOS and is the recommended approach
|
||||
for most users. The <a href="/install/cli">command-line installation guide</a> is the
|
||||
more traditional approach to installing GrapheneOS.</p>
|
||||
|
||||
<p>If you have trouble with the installation process, ask for help on the
|
||||
<a href="/contact#community">official GrapheneOS chat channel</a>. There are almost
|
||||
always people around willing to help with it. Before asking for help, make an attempt
|
||||
to follow the guide on your own and then ask for help with anything you get stuck
|
||||
on.</p>
|
||||
|
||||
<nav id="table-of-contents">
|
||||
<h2><a href="#table-of-contents">Table of contents</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#prerequisites">Prerequisites</a></li>
|
||||
<li><a href="#enabling-oem-unlocking">Enabling OEM unlocking</a></li>
|
||||
<li><a href="#flashing-as-non-root">Flashing as non-root</a></li>
|
||||
<li><a href="#working-around-fwupd-bugs-on-linux-distributions">Working around fwupd bugs on Linux distributions</a></li>
|
||||
<li><a href="#booting-into-the-bootloader-interface">Booting into the bootloader interface</a></li>
|
||||
<li><a href="#connecting-device">Connecting the device</a></li>
|
||||
<li><a href="#unlocking-the-bootloader">Unlocking the bootloader</a></li>
|
||||
<li><a href="#obtaining-factory-images">Obtaining factory images</a></li>
|
||||
<li><a href="#flashing-factory-images">Flashing factory images</a></li>
|
||||
<li><a href="#locking-the-bootloader">Locking the bootloader</a></li>
|
||||
<li>
|
||||
<a href="#post-installation">Post-installation</a>
|
||||
<ul>
|
||||
<li><a href="#booting">Booting</a></li>
|
||||
<li><a href="#disabling-oem-unlocking">Disabling OEM unlocking</a></li>
|
||||
<li>
|
||||
<a href="#verifying-installation">Verifying installation</a>
|
||||
<ul>
|
||||
<li><a href="#verified-boot-key-hash">Verified boot key hash</a></li>
|
||||
<li><a href="#hardware-based-attestation">Hardware-based attestation</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#further-information">Further information</a></li>
|
||||
<li><a href="#replacing-grapheneos-with-the-stock-os">Replacing GrapheneOS with the stock OS</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<section id="prerequisites">
|
||||
<h2><a href="#prerequisites">Prerequisites</a></h2>
|
||||
|
||||
<p>You need a computer for running the web installer with at least 2GB of free
|
||||
memory available and 32GB of free storage space. The web installer can be run on an
|
||||
Android phone or tablet, unlike the command-line installation.</p>
|
||||
|
||||
<p>You need a USB cable for attaching the device to the computer performing the
|
||||
installation. Whenever possible, use the high quality standards compliant USB-C
|
||||
cable packaged with the device. If your computer doesn't have any USB-C ports,
|
||||
you'll need a high quality USB-C to USB-A cable. You should avoid using a USB hub
|
||||
such as the front panel on a desktop computer case. Connect directly to a rear port
|
||||
on a desktop or the ports on a laptop. Many widely distributed USB cables and hubs
|
||||
are broken and are the most common source of issues for installing GrapheneOS.</p>
|
||||
|
||||
<p>Installing from an OS in a virtual machine is not recommended. USB passthrough
|
||||
is often not reliable. To rule out these problems, install from an OS running on
|
||||
bare metal. Virtual machines are also often configured to have overly limited
|
||||
memory and storage space.</p>
|
||||
|
||||
<p>Officially supported operating systems for the web install method:</p>
|
||||
|
||||
<ul>
|
||||
<li>Windows 10</li>
|
||||
<li>Windows 11</li>
|
||||
<li>macOS Ventura (13)</li>
|
||||
<li>macOS Sonoma (14)</li>
|
||||
<li>macOS Sequoia (15)</li>
|
||||
<li>Arch Linux</li>
|
||||
<li>Debian 11 (bullseye)</li>
|
||||
<li>Debian 12 (bookworm)</li>
|
||||
<li>Ubuntu 20.04 LTS</li>
|
||||
<li>Ubuntu 22.04 LTS</li>
|
||||
<li>Ubuntu 24.04 LTS</li>
|
||||
<li>Ubuntu 24.10</li>
|
||||
<li>Linux Mint 20 (follow Ubuntu 20.04 LTS instructions)</li>
|
||||
<li>Linux Mint 21 (follow Ubuntu 22.04 LTS instructions)</li>
|
||||
<li>Linux Mint 22 (follow Ubuntu 24.04 LTS instructions)</li>
|
||||
<li>Linux Mint Debian Edition 6 (follow Debian 12 instructions)</li>
|
||||
<li>ChromeOS</li>
|
||||
<li>GrapheneOS</li>
|
||||
<li>Android 12 with Play Protect certification</li>
|
||||
<li>Android 13 with Play Protect certification</li>
|
||||
<li>Android 14 with Play Protect certification</li>
|
||||
<li>Android 15 with Play Protect certification</li>
|
||||
</ul>
|
||||
|
||||
<p>Make sure your operating system is up-to-date before proceeding.</p>
|
||||
|
||||
<p>Officially supported browsers for the web install method:</p>
|
||||
|
||||
<ul>
|
||||
<li>Chromium (outside Ubuntu, since they ship a broken Snap package without working WebUSB)</li>
|
||||
<li>Vanadium (GrapheneOS)</li>
|
||||
<li>Google Chrome</li>
|
||||
<li>Microsoft Edge</li>
|
||||
<li>Brave (with Brave Shields disabled, since it caps storage usage at a low value to avoid fingerprinting available storage)</li>
|
||||
</ul>
|
||||
|
||||
<p>On Android, disable desktop mode for the browser since it currently prevents our
|
||||
web installer from detecting Android and handling needing to request permission to
|
||||
reconnect to the device after each reboot. Desktop mode is enabled by default on
|
||||
large tablets with at least 8GB of RAM such as the Pixel Tablet.</p>
|
||||
|
||||
<p>You should avoid Flatpak and Snap versions of browsers, as they're known to cause issues during the installation process.</p>
|
||||
|
||||
<p>Make sure your browser is up-to-date before proceeding.</p>
|
||||
|
||||
<p>Do not use Incognito or other private browsing modes. These modes usually
|
||||
prevent the web installer from having enough storage space to extract the
|
||||
downloaded release.</p>
|
||||
|
||||
<p>You need one of the <a href="/faq#supported-devices">officially supported
|
||||
devices</a>. To make sure that the device can be unlocked to install GrapheneOS,
|
||||
avoid carrier variants of the devices. Carrier variants of Pixels use the same stock
|
||||
OS and firmware with a non-zero carrier id flashed onto the persist partition in the
|
||||
factory. The carrier id activates carrier-specific configuration in the stock OS
|
||||
including disabling carrier and bootloader unlocking. The carrier may be able to
|
||||
remotely disable this, but their support staff may not be aware and they probably
|
||||
won't do it. Get a carrier agnostic device to avoid the risk and potential hassle.
|
||||
If you CAN figure out a way to unlock a carrier device, it isn't a problem as
|
||||
GrapheneOS can just ignore the carrier id and the hardware is the same.</p>
|
||||
|
||||
<p>It's best practice to update the device before installing GrapheneOS to have
|
||||
the latest firmware for connecting the device to the computer and performing the
|
||||
early flashing process. Either way, GrapheneOS flashes the latest firmware early
|
||||
in the installation process.</p>
|
||||
</section>
|
||||
|
||||
<section id="enabling-oem-unlocking">
|
||||
<h2><a href="#enabling-oem-unlocking">Enabling OEM unlocking</a></h2>
|
||||
|
||||
<p>OEM unlocking needs to be enabled from within the operating system.</p>
|
||||
|
||||
<p>Enable the developer options menu by going to <b>Settings <span
|
||||
aria-label="and then">></span> About phone/tablet</b> and repeatedly
|
||||
pressing the <b>Build number</b> menu entry until developer mode is enabled.</p>
|
||||
|
||||
<p>Next, go to <b>Settings <span aria-label="and then">></span>
|
||||
System <span aria-label="and then">></span> Developer options</b> and
|
||||
toggle on the <b>OEM unlocking</b> setting. On device model variants (SKUs) which
|
||||
support being sold as locked devices by carriers, enabling <b>OEM unlocking</b>
|
||||
requires internet access so that the stock OS can check if the device was sold as
|
||||
locked by a carrier.</p>
|
||||
|
||||
<p>For the Pixel 6a, OEM unlocking won't work with the version of the stock OS
|
||||
from the factory. You need to update it to the June 2022 release or later via an
|
||||
over-the-air update. After you've updated it you'll also need to factory reset
|
||||
the device to fix OEM unlocking.</p>
|
||||
</section>
|
||||
|
||||
<section id="flashing-as-non-root">
|
||||
<h2><a href="#flashing-as-non-root">Flashing as non-root</a></h2>
|
||||
|
||||
<p>On traditional Linux distributions, USB devices cannot be used as non-root
|
||||
without udev rules for each type of device. This is not an issue for other
|
||||
platforms.</p>
|
||||
|
||||
<p>On Arch Linux, install the <code>android-udev</code> package. On Debian and
|
||||
Ubuntu, install the <code>android-sdk-platform-tools-common</code> package.</p>
|
||||
</section>
|
||||
|
||||
<section id="working-around-fwupd-bugs-on-linux-distributions">
|
||||
<h2><a href="#working-around-fwupd-bug-on-linux-distributions">Working around fwupd bugs on Linux distributions</a></h2>
|
||||
|
||||
<p>The fwupd software often used on Linux distributions for updating firmware is
|
||||
known to incorrectly connect to arbitrary devices using the fastboot protocol which
|
||||
will block using them for the intended purpose. This can result in receiving an
|
||||
error about the USB device already being in use (claimed) when trying to connect to
|
||||
it for the intended purpose.</p>
|
||||
|
||||
<p>You can stop fwupd with the following command:</p>
|
||||
|
||||
<pre>sudo systemctl stop fwupd.service</pre>
|
||||
|
||||
<p>This doesn't disable the service and it will start again on reboot.</p>
|
||||
</section>
|
||||
|
||||
<section id="booting-into-the-bootloader-interface">
|
||||
<h2><a href="#booting-into-the-bootloader-interface">Booting into the bootloader interface</a></h2>
|
||||
|
||||
<p>You need to boot your device into the bootloader interface. To do this, you need
|
||||
to hold the volume down button while the device boots.</p>
|
||||
|
||||
<p>The easiest approach is to reboot the device and begin holding the volume down
|
||||
button until it boots up into the bootloader interface.</p>
|
||||
|
||||
<p>Alternatively, turn off the device, then boot it up while holding the volume
|
||||
down button during the boot process. You can either boot it with the power button
|
||||
or by plugging it in as required in the next section.</p>
|
||||
|
||||
<p>This step is not complete until your device displays a red warning triangle
|
||||
and the words "Fastboot Mode". You must not press the device's power button
|
||||
to activate the "Start" menu item, because the device must remain paused in
|
||||
Fastboot mode for the installer to connect to it.</p>
|
||||
</section>
|
||||
|
||||
<section id="connecting-device">
|
||||
<h2><a href="#connecting-device">Connecting the device</a></h2>
|
||||
|
||||
<p>Connect the device to the computer. On Linux, you'll need to do this again if
|
||||
you didn't have the udev rules set up when you connected it.</p>
|
||||
|
||||
<p>Current Windows 10 and Windows 11 include a generic driver usable for fastboot
|
||||
and no longer require installing a driver for installation on the Pixel 4a (5G) or
|
||||
later. It isn't enough for legacy 4th generation Pixels due to the driver not
|
||||
handling fastbootd, so you still need the driver for those. Outdated Windows
|
||||
versions will still need the driver for non-obsolete devices too. You can obtain the
|
||||
driver from Windows Update which will detect it as an optional update when the
|
||||
device is booted into the bootloader interface and connected to the computer. Open
|
||||
Windows Update, run a check for updates and then open the "View optional updates"
|
||||
interface. Install the driver for the Android bootloader interface as an optional
|
||||
update, which will show up as "LeMobile Android Device" due to USB ID overlap. An
|
||||
alternative approach to obtaining the Windows fastboot driver is to obtain the <a
|
||||
href="https://developer.android.com/studio/run/win-usb">latest driver for
|
||||
Pixels</a> from Google and then <a href="https://developer.android.com/studio/run/oem-usb#InstallingDriver">manually
|
||||
install it with the Windows Device Manager</a>.</p>
|
||||
|
||||
<p>For the Pixel Tablet, disconnect it from the stand before continuing. The stand
|
||||
uses USB to provide charging and audio output, but the tablet lacks support for
|
||||
using both the stand and USB port at the same time.</p>
|
||||
</section>
|
||||
|
||||
<section id="unlocking-the-bootloader">
|
||||
<h2><a href="#unlocking-the-bootloader">Unlocking the bootloader</a></h2>
|
||||
|
||||
<p>Unlock the bootloader to allow flashing the OS and firmware:</p>
|
||||
|
||||
<button id="unlock-bootloader-button" disabled="">Unlock bootloader</button>
|
||||
|
||||
<p>The command needs to be confirmed on the device and will wipe all data. Use one
|
||||
of the volume buttons to switch the selection to accepting it and the power button to
|
||||
confirm.</p>
|
||||
|
||||
<p><strong id="unlock-bootloader-status"></strong></p>
|
||||
</section>
|
||||
|
||||
<section id="obtaining-factory-images">
|
||||
<h2><a href="#obtaining-factory-images">Obtaining factory images</a></h2>
|
||||
|
||||
<p>You need to obtain the GrapheneOS factory images for your device to proceed with
|
||||
the installation process.</p>
|
||||
|
||||
<p>Press the button below to start the download:</p>
|
||||
|
||||
<button id="download-release-button" disabled="">Download release</button>
|
||||
|
||||
<p id="download-release-status-container" hidden="hidden">
|
||||
<strong id="download-release-status"></strong>
|
||||
<br/>
|
||||
<progress id="download-release-progress" hidden="hidden" max="1" value="0"></progress>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="flashing-factory-images">
|
||||
<h2><a href="#flashing-factory-images">Flashing factory images</a></h2>
|
||||
|
||||
<p>The initial install will be performed by flashing the factory images. This will
|
||||
replace the existing OS installation and wipe all the existing data.</p>
|
||||
|
||||
<button id="flash-release-button" disabled="">Flash release</button>
|
||||
|
||||
|
||||
<p>Wait for the flashing process to complete. It will automatically handle
|
||||
flashing the firmware, rebooting into the bootloader interface and flashing the OS.
|
||||
Avoid interacting with the device until the flashing script is finished. Then,
|
||||
proceed to <a href="#locking-the-bootloader">locking the bootloader</a> before using
|
||||
the device as locking wipes the data again.</p>
|
||||
|
||||
<p id="flash-release-status-container" hidden="hidden">
|
||||
<strong id="flash-release-status"></strong>
|
||||
<br/>
|
||||
|
||||
<!-- These appear as part of the status, one at a time -->
|
||||
<progress id="flash-release-progress" hidden="hidden" max="1" value="0"></progress>
|
||||
<button id="flash-reconnect-button" hidden="hidden"><strong>Reconnect device</strong></button>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="locking-the-bootloader">
|
||||
<h2><a href="#locking-the-bootloader">Locking the bootloader</a></h2>
|
||||
|
||||
<p>Locking the bootloader is important as it enables full verified boot. It also
|
||||
prevents using fastboot to flash, format or erase partitions. Verified boot will
|
||||
detect modifications to any of the OS partitions and it will prevent reading any
|
||||
modified / corrupted data. If changes are detected, error correction data is used
|
||||
to attempt to obtain the original data at which point it's verified again which
|
||||
makes verified boot robust to non-malicious corruption.</p>
|
||||
|
||||
<p>In the bootloader interface, set it to locked:</p>
|
||||
|
||||
<button id="lock-bootloader-button" disabled="">Lock bootloader</button>
|
||||
|
||||
<p>The command needs to be confirmed on the device and will wipe all data. Use one
|
||||
of the volume buttons to switch the selection to accepting it and the power button
|
||||
to confirm.</p>
|
||||
|
||||
<p><strong id="lock-bootloader-status"></strong></p>
|
||||
</section>
|
||||
|
||||
<section id="post-installation">
|
||||
<h2><a href="#post-installation">Post-installation</a></h2>
|
||||
|
||||
<section id="booting">
|
||||
<h3><a href="#booting">Booting</a></h3>
|
||||
|
||||
<p>You've now successfully installed GrapheneOS and can boot it. Pressing the
|
||||
power button with the default Start option selected in the bootloader
|
||||
interface will boot the OS.</p>
|
||||
</section>
|
||||
|
||||
<section id="disabling-oem-unlocking">
|
||||
<h3><a href="#disabling-oem-unlocking">Disabling OEM unlocking</a></h3>
|
||||
|
||||
<p>During first setup, the final screen will contain a toggle regarding OEM
|
||||
unlocking which is checked by default. This will disable OEM unlocking, which is
|
||||
recommended.</p>
|
||||
|
||||
<p>If you need to enable or disable OEM unlocking in the future, it can be done
|
||||
in the developer settings menu within the operating system.</p>
|
||||
</section>
|
||||
|
||||
<section id="verifying-installation">
|
||||
<h3><a href="#verifying-installation">Verifying installation</a></h3>
|
||||
|
||||
<p>The verified boot and attestation features provided by the supported
|
||||
devices can be used to verify that the hardware, firmware and GrapheneOS
|
||||
installation are genuine. Even if the computer you used to flash GrapheneOS
|
||||
was compromised and an attacker replaced GrapheneOS with their own malicious
|
||||
OS, it can be detected with these features.</p>
|
||||
|
||||
<p>Verified boot verifies the entirety of the firmware and OS images on every
|
||||
boot. The public key for the firmware images is burned into fuses in the SoC at
|
||||
the factory. Firmware security updates also update the rollback index burned
|
||||
into fuses to provide rollback protection.</p>
|
||||
|
||||
<p>The final firmware boot stage before the OS is responsible for verifying
|
||||
it. For the stock OS, it uses a hard-wired public key. Installing GrapheneOS
|
||||
flashes the GrapheneOS verified boot public key to the secure element. Each
|
||||
boot, this key is loaded and used to verify the OS. For both the stock OS and
|
||||
GrapheneOS, a rollback index based on the security patch level is loaded from
|
||||
the secure element to provide rollback protection.</p>
|
||||
|
||||
<section id="verified-boot-key-hash">
|
||||
<h3><a href="#verified-boot-key-hash">Verified boot key hash</a></h3>
|
||||
|
||||
<p>When loading an alternate OS, the device shows a yellow notice on boot
|
||||
with the ID of the alternate OS based on the sha256 of the verified boot
|
||||
public key. 4th and 5th generation Pixels only show the first 32 bits of
|
||||
the hash so you can't use this approach. 6th generation Pixels onwards
|
||||
show the full hash and you can compare it against the official GrapheneOS
|
||||
verified boot key hashes below:</p>
|
||||
|
||||
<ul>
|
||||
<li>Pixel 9a: <code>0508de44ee00bfb49ece32c418af1896391abde0f05b64f41bc9a2dfb589445b</code></li>
|
||||
<li>Pixel 9 Pro Fold: <code>af4d2c6e62be0fec54f0271b9776ff061dd8392d9f51cf6ab1551d346679e24c</code></li>
|
||||
<li>Pixel 9 Pro XL: <code>55d3c2323db91bb91f20d38d015e85112d038f6b6b5738fe352c1a80dba57023</code></li>
|
||||
<li>Pixel 9 Pro: <code>f729cab861da1b83fdfab402fc9480758f2ae78ee0b61c1f2137dd1ab7076e86</code></li>
|
||||
<li>Pixel 9: <code>9e6a8f3e0d761a780179f93acd5721ba1ab7c8c537c7761073c0a754b0e932de</code></li>
|
||||
<li>Pixel 8a: <code>096b8bd6d44527a24ac1564b308839f67e78202185cbff9cfdcb10e63250bc5e</code></li>
|
||||
<li>Pixel 8 Pro: <code>896db2d09d84e1d6bb747002b8a114950b946e5825772a9d48ba7eb01d118c1c</code></li>
|
||||
<li>Pixel 8: <code>cd7479653aa88208f9f03034810ef9b7b0af8a9d41e2000e458ac403a2acb233</code></li>
|
||||
<li>Pixel Fold: <code>ee0c9dfef6f55a878538b0dbf7e78e3bc3f1a13c8c44839b095fe26dd5fe2842</code></li>
|
||||
<li>Pixel Tablet: <code>94df136e6c6aa08dc26580af46f36419b5f9baf46039db076f5295b91aaff230</code></li>
|
||||
<li>Pixel 7a: <code>508d75dea10c5cbc3e7632260fc0b59f6055a8a49dd84e693b6d8899edbb01e4</code></li>
|
||||
<li>Pixel 7 Pro: <code>bc1c0dd95664604382bb888412026422742eb333071ea0b2d19036217d49182f</code></li>
|
||||
<li>Pixel 7: <code>3efe5392be3ac38afb894d13de639e521675e62571a8a9b3ef9fc8c44fd17fa1</code></li>
|
||||
<li>Pixel 6a: <code>08c860350a9600692d10c8512f7b8e80707757468e8fbfeea2a870c0a83d6031</code></li>
|
||||
<li>Pixel 6 Pro: <code>439b76524d94c40652ce1bf0d8243773c634d2f99ba3160d8d02aa5e29ff925c</code></li>
|
||||
<li>Pixel 6: <code>f0a890375d1405e62ebfd87e8d3f475f948ef031bbf9ddd516d5f600a23677e8</code></li>
|
||||
</ul>
|
||||
|
||||
<p>Checking this is useful after installation, but you don't need to check
|
||||
it manually for verified boot to work. The verified boot public key
|
||||
flashed to the secure element can only be changed when the device is
|
||||
unlocked. Unlocking the device performs the same wiping of the secure
|
||||
element as a factory reset and prevents data from being recovered even if
|
||||
the SSD was cloned and your passphrase(s) are obtained because the
|
||||
encryption keys can no longer be derived anymore. The verified boot key is
|
||||
also one of the inputs for deriving the encryption keys in addition to the
|
||||
user's lock method(s) and random token(s) on the secure element.</p>
|
||||
</section>
|
||||
|
||||
<section id="hardware-based-attestation">
|
||||
<h3><a href="#hardware-based-attestation">Hardware-based attestation</a></h3>
|
||||
|
||||
<p>GrapheneOS provides our Auditor app for using a combination of the
|
||||
verified boot and attestation features to verify that the hardware,
|
||||
firmware and operating system are genuine along with providing other
|
||||
useful data from the hardware and operating system.</p>
|
||||
|
||||
<p>Since the purpose of Auditor is to obtain information about the device
|
||||
without trusting it to be honest, results aren't shown on the device being
|
||||
verified. You need a 2nd Android device running Auditor for local QR code
|
||||
based verification. You can also use our optional device integrity
|
||||
monitoring service for automatic scheduled verifications with support for
|
||||
email alerts.</p>
|
||||
|
||||
<p>See the <a href="https://attestation.app/tutorial">Auditor tutorial</a>
|
||||
for a guide.</p>
|
||||
|
||||
<p>Auditor is primarily based on a pairing model where it generates a
|
||||
hardware backed signing key and hardware backed attestation signing key
|
||||
and pins them as part of the initial verification. The first verification
|
||||
is bootstrapped based on chaining trust to one of the Android attestation
|
||||
roots. After the first verification, it provides a highly secure system
|
||||
for obtaining information about the device going forward. An attacker
|
||||
could bypass the initial verification with a leaked attestation key or by
|
||||
proxying to another device with the device model, OS and patch level that
|
||||
the user is expecting. Proxying to another device will be addressed in the
|
||||
future with optional support for the hardware serial number attestation
|
||||
feature.</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="further-information">
|
||||
<h3><a href="#further-information">Further information</a></h3>
|
||||
|
||||
<p>Please look through the <a href="/usage">usage guide</a> and
|
||||
<a href="/faq">FAQ</a> for more information. If you have further questions not
|
||||
covered by the site, join the <a href="/contact#community">official GrapheneOS
|
||||
chat channels</a> and ask the questions in the appropriate channel.</p>
|
||||
</section>
|
||||
|
||||
<section id="replacing-grapheneos-with-the-stock-os">
|
||||
<h3><a href="#replacing-grapheneos-with-the-stock-os">Replacing GrapheneOS with the stock OS</a></h3>
|
||||
|
||||
<p>Installation of the stock OS via the stock factory images is similar to the
|
||||
process described above but with
|
||||
<a href="https://flash.android.com/back-to-public">Google's web flashing
|
||||
tool</a>. However, before flashing and locking, there's an additional step to
|
||||
fully revert the device to a clean factory state.</p>
|
||||
|
||||
<p>The GrapheneOS factory images flash a non-stock Android Verified Boot key which
|
||||
needs to be erased to fully revert back to a stock device state. Before flashing the
|
||||
stock factory images, you should boot the device into fastboot mode and make sure the
|
||||
bootloader is unlocked. Then erase the custom Android Verified Boot key to untrust it:</p>
|
||||
|
||||
<button id="remove-custom-key-button" disabled="">Remove non-stock key</button>
|
||||
|
||||
<p><strong id="remove-custom-key-status"></strong></p>
|
||||
</section>
|
||||
</section>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
165
static/js/oneko.js
Normal file
@ -0,0 +1,165 @@
|
||||
(function oneko() {
|
||||
const nekoEl = document.createElement("div");
|
||||
let nekoPosX = 32;
|
||||
let nekoPosY = 32;
|
||||
let mousePosX = 0;
|
||||
let mousePosY = 0;
|
||||
let frameCount = 0;
|
||||
let idleTime = 0;
|
||||
let idleAnimation = null;
|
||||
let idleAnimationFrame = 0;
|
||||
const nekoSpeed = 10;
|
||||
const spriteSets = {
|
||||
idle: [[-3, -3]],
|
||||
alert: [[-7, -3]],
|
||||
scratch: [
|
||||
[-5, 0],
|
||||
[-6, 0],
|
||||
[-7, 0],
|
||||
],
|
||||
tired: [[-3, -2]],
|
||||
sleeping: [
|
||||
[-2, 0],
|
||||
[-2, -1],
|
||||
],
|
||||
N: [
|
||||
[-1, -2],
|
||||
[-1, -3],
|
||||
],
|
||||
NE: [
|
||||
[0, -2],
|
||||
[0, -3],
|
||||
],
|
||||
E: [
|
||||
[-3, 0],
|
||||
[-3, -1],
|
||||
],
|
||||
SE: [
|
||||
[-5, -1],
|
||||
[-5, -2],
|
||||
],
|
||||
S: [
|
||||
[-6, -3],
|
||||
[-7, -2],
|
||||
],
|
||||
SW: [
|
||||
[-5, -3],
|
||||
[-6, -1],
|
||||
],
|
||||
W: [
|
||||
[-4, -2],
|
||||
[-4, -3],
|
||||
],
|
||||
NW: [
|
||||
[-1, 0],
|
||||
[-1, -1],
|
||||
],
|
||||
};
|
||||
function create() {
|
||||
nekoEl.id = "oneko";
|
||||
nekoEl.style.width = "32px";
|
||||
nekoEl.style.height = "32px";
|
||||
nekoEl.style.position = "fixed";
|
||||
nekoEl.style.pointerEvents = "none";
|
||||
nekoEl.style.backgroundImage = "url('/oneko.gif')";
|
||||
nekoEl.style.imageRendering = "pixelated";
|
||||
nekoEl.style.left = "16px";
|
||||
nekoEl.style.top = "16px";
|
||||
|
||||
document.body.appendChild(nekoEl);
|
||||
|
||||
document.onmousemove = (event) => {
|
||||
mousePosX = event.clientX;
|
||||
mousePosY = event.clientY;
|
||||
};
|
||||
|
||||
window.onekoInterval = setInterval(frame, 100);
|
||||
}
|
||||
|
||||
function setSprite(name, frame) {
|
||||
const sprite = spriteSets[name][frame % spriteSets[name].length];
|
||||
nekoEl.style.backgroundPosition = `${sprite[0] * 32}px ${
|
||||
sprite[1] * 32
|
||||
}px`;
|
||||
}
|
||||
|
||||
function resetIdleAnimation() {
|
||||
idleAnimation = null;
|
||||
idleAnimationFrame = 0;
|
||||
}
|
||||
|
||||
function idle() {
|
||||
idleTime += 1;
|
||||
|
||||
// every ~ 20 seconds
|
||||
if (
|
||||
idleTime > 10 &&
|
||||
Math.floor(Math.random() * 200) == 0 &&
|
||||
idleAnimation == null
|
||||
) {
|
||||
idleAnimation = ["sleeping", "scratch"][
|
||||
Math.floor(Math.random() * 2)
|
||||
];
|
||||
}
|
||||
|
||||
switch (idleAnimation) {
|
||||
case "sleeping":
|
||||
if (idleAnimationFrame < 8) {
|
||||
setSprite("tired", 0);
|
||||
break;
|
||||
}
|
||||
setSprite("sleeping", Math.floor(idleAnimationFrame / 4));
|
||||
if (idleAnimationFrame > 192) {
|
||||
resetIdleAnimation();
|
||||
}
|
||||
break;
|
||||
case "scratch":
|
||||
setSprite("scratch", idleAnimationFrame);
|
||||
if (idleAnimationFrame > 9) {
|
||||
resetIdleAnimation();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
setSprite("idle", 0);
|
||||
return;
|
||||
}
|
||||
idleAnimationFrame += 1;
|
||||
}
|
||||
|
||||
function frame() {
|
||||
frameCount += 1;
|
||||
const diffX = nekoPosX - mousePosX;
|
||||
const diffY = nekoPosY - mousePosY;
|
||||
const distance = Math.sqrt(diffX ** 2 + diffY ** 2);
|
||||
|
||||
if (distance < nekoSpeed || distance < 48) {
|
||||
idle();
|
||||
return;
|
||||
}
|
||||
|
||||
idleAnimation = null;
|
||||
idleAnimationFrame = 0;
|
||||
|
||||
if (idleTime > 1) {
|
||||
setSprite("alert", 0);
|
||||
// count down after being alerted before moving
|
||||
idleTime = Math.min(idleTime, 7);
|
||||
idleTime -= 1;
|
||||
return;
|
||||
}
|
||||
|
||||
let direction = diffY / distance > 0.5 ? "N" : "";
|
||||
direction += diffY / distance < -0.5 ? "S" : "";
|
||||
direction += diffX / distance > 0.5 ? "W" : "";
|
||||
direction += diffX / distance < -0.5 ? "E" : "";
|
||||
setSprite(direction, frameCount);
|
||||
|
||||
nekoPosX -= (diffX / distance) * nekoSpeed;
|
||||
nekoPosY -= (diffY / distance) * nekoSpeed;
|
||||
|
||||
nekoEl.style.left = `${nekoPosX - 16}px`;
|
||||
nekoEl.style.top = `${nekoPosY - 16}px`;
|
||||
}
|
||||
|
||||
create();
|
||||
})();
|
@ -1,106 +0,0 @@
|
||||
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT
|
||||
|
||||
// Client-side redirects for fragments (anchors)
|
||||
//
|
||||
// It should be possible to do this with either HTML or server-side redirects, but it was never
|
||||
// implemented or standardized. For reference:
|
||||
//
|
||||
// https://www.w3.org/People/Bos/redirect
|
||||
// https://www.w3.org/Protocols/HTTP/Fragment/draft-bos-http-redirect-00.txt
|
||||
|
||||
const redirects = new Map([
|
||||
// removed main page sections
|
||||
["/#copyright-and-licensing", "/faq#copyright-and-licensing"],
|
||||
["/#history", "/history"],
|
||||
["/#roadmap", "/faq#roadmap"],
|
||||
["/#upstream", "/faq#upstream"],
|
||||
|
||||
["/usage#default-connections", "/faq#default-connections"],
|
||||
["/usage#sandboxed-google-play-esim", "/usage#esim-support"],
|
||||
["/usage#sandboxed-play-services", "/usage#sandboxed-google-play"],
|
||||
["/usage#sandboxed-play-services-installation", "/usage#sandboxed-google-play-installation"],
|
||||
["/usage#sandboxed-play-services-limitations", "/usage#sandboxed-google-play-limitations"],
|
||||
["/usage#google-camera", "/usage#pixel-camera"],
|
||||
["/usage#usb-peripherals", "/usage#usb-c-port-and-pogo-pins-control"],
|
||||
|
||||
["/faq#dns", "/faq#custom-dns"],
|
||||
["/faq#when-devices", "/faq#future-devices"],
|
||||
|
||||
["/features#usb-c-port-control", "/features#usb-c-port-and-pogo-pins-control"],
|
||||
["/features#Two-factor-fingerprint-unlock", "/features#two-factor-fingerprint-unlock"],
|
||||
|
||||
["/hiring#qualitifations", "/hiring#qualifications"],
|
||||
|
||||
["/install/cli#fastboot-as-non-root", "/install/cli#flashing-as-non-root"],
|
||||
["/install/cli#obtaining-signify", "/install/cli#obtaining-openssh"],
|
||||
["/install/web#fastboot-as-non-root", "/install/web#flashing-as-non-root"],
|
||||
|
||||
["/install/cli#working-around-fwupd-bug-on-linux-distributions", "/install/cli#working-around-fwupd-bugs-on-linux-distributions"],
|
||||
["/install/web#working-around-fwupd-bug-on-linux-distributions", "/install/web#working-around-fwupd-bugs-on-linux-distributions"],
|
||||
|
||||
["/build#enabling-updatable-apex-components", "/build#apex-components"],
|
||||
["/build#kernel-6th-generation-pixels", "/build#kernel-6th-through-9th-generation-pixels"],
|
||||
["/build#kernel-7th-generation-pixels", "/build#kernel-6th-through-9th-generation-pixels"],
|
||||
["/build#kernel-6th-and-7th-generation-pixels", "/build#kernel-6th-through-9th-generation-pixels"],
|
||||
["/build#kernel-8th-generation-pixels", "/build#kernel-6th-through-9th-generation-pixels"],
|
||||
["/build#kernel-9th-generation-pixels", "/build#kernel-6th-through-9th-generation-pixels"],
|
||||
|
||||
// legacy devices
|
||||
["/releases#marlin-stable", "/faq#legacy-devices"],
|
||||
["/releases#marlin-beta", "/faq#legacy-devices"],
|
||||
["/releases#sailfish-stable", "/faq#legacy-devices"],
|
||||
["/releases#sailfish-beta", "/faq#legacy-devices"],
|
||||
["/releases#taimen-stable", "/faq#legacy-devices"],
|
||||
["/releases#taimen-beta", "/faq#legacy-devices"],
|
||||
["/releases#walleye-stable", "/faq#legacy-devices"],
|
||||
["/releases#walleye-beta", "/faq#legacy-devices"],
|
||||
["/releases#bonito-stable", "/faq#legacy-devices"],
|
||||
["/releases#bonito-beta", "/faq#legacy-devices"],
|
||||
["/releases#sargo-stable", "/faq#legacy-devices"],
|
||||
["/releases#sargo-beta", "/faq#legacy-devices"],
|
||||
["/releases#crosshatch-stable", "/faq#legacy-devices"],
|
||||
["/releases#crosshatch-beta", "/faq#legacy-devices"],
|
||||
["/releases#blueline-stable", "/faq#legacy-devices"],
|
||||
["/releases#blueline-beta", "/faq#legacy-devices"],
|
||||
|
||||
// legacy servers
|
||||
["/articles/grapheneos-servers#apps.grapheneos.org", "/articles/grapheneos-servers#releases.grapheneos.org"],
|
||||
["/articles/grapheneos-servers#time.grapheneos.org", "/articles/grapheneos-servers#grapheneos.network"],
|
||||
|
||||
// preserve links to CLI install guide from when it was /install
|
||||
["/install/#prerequisites", "/install/cli#prerequisites"],
|
||||
["/install/#enabling-oem-unlocking", "/install/cli#enabling-oem-unlocking"],
|
||||
["/install/#opening-terminal", "/install/cli#opening-terminal"],
|
||||
["/install/#obtaining-fastboot", "/install/cli#obtaining-fastboot"],
|
||||
["/install/#standalone-platform-tools", "/install/cli#standalone-platform-tools"],
|
||||
["/install/#checking-fastboot-version", "/install/cli#checking-fastboot-version"],
|
||||
["/install/#fastboot-as-non-root", "/install/cli#flashing-as-non-root"],
|
||||
["/install/#connecting-phone", "/install/cli#connecting-phone"],
|
||||
["/install/#unlocking-the-bootloader", "/install/cli#unlocking-the-bootloader"],
|
||||
["/install/#obtaining-signify", "/install/cli#obtaining-openssh"],
|
||||
["/install/#obtaining-factory-images", "/install/cli#obtaining-factory-images"],
|
||||
["/install/#flashing-factory-images", "/install/cli#flashing-factory-images"],
|
||||
["/install/#troubleshooting", "/install/cli#troubleshooting"],
|
||||
["/install/#locking-the-bootloader", "/install/cli#locking-the-bootloader"],
|
||||
["/install/#post-installation", "/install/cli#post-installation"],
|
||||
["/install/#booting", "/install/cli#booting"],
|
||||
["/install/#disabling-oem-unlocking", "/install/cli#disabling-oem-unlocking"],
|
||||
["/install/#replacing-grapheneos-with-the-stock-os", "/install/cli#replacing-grapheneos-with-the-stock-os"],
|
||||
["/install/#further-information", "/install/cli#further-information"],
|
||||
["/install/web#connecting-phone", "/install/web#connecting-device"],
|
||||
["/install/cli#connecting-phone", "/install/cli#connecting-device"],
|
||||
]);
|
||||
|
||||
function handleHash() {
|
||||
if (window.location.hash) {
|
||||
const redirect = redirects.get(window.location.pathname + window.location.hash);
|
||||
if (redirect) {
|
||||
window.location.replace(redirect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleHash();
|
||||
addEventListener("hashchange", handleHash, false);
|
||||
|
||||
// @license-end
|
@ -1,49 +0,0 @@
|
||||
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT
|
||||
|
||||
const baseUrl = "https://releases.grapheneos.org/";
|
||||
const devices = ["comet", "komodo", "caiman", "tokay", "akita", "husky", "shiba", "felix", "tangorpro", "lynx", "cheetah", "panther", "bluejay", "raven", "oriole", "barbet", "redfin", "bramble", "sunfish", "coral", "flame"];
|
||||
const legacyFactoryDevices = new Set(["sunfish", "coral", "flame"]);
|
||||
const channels = ["stable", "beta", "alpha"];
|
||||
const delayMs = 1000 * 60 * 5;
|
||||
|
||||
async function updateReleases() {
|
||||
const requests = [];
|
||||
|
||||
for (const channel of channels) {
|
||||
for (const device of devices) {
|
||||
requests.push(fetch(`${baseUrl}${device}-${channel}`).then(response => {
|
||||
if (!response.ok) {
|
||||
return Promise.reject();
|
||||
}
|
||||
return response.text();
|
||||
}).then(text => {
|
||||
const metadata = text.trim().split(" ");
|
||||
|
||||
const factoryFormat = legacyFactoryDevices.has(device) ? "factory" : "install";
|
||||
const factoryFilename = `${device}-${factoryFormat}-${metadata[0]}.zip`;
|
||||
const factoryUrl = baseUrl + factoryFilename;
|
||||
|
||||
const updateFilename = `${device}-ota_update-${metadata[0]}.zip`;
|
||||
const updateUrl = baseUrl + updateFilename;
|
||||
|
||||
const release = document.getElementById(`${device}-${channel}`);
|
||||
const links = release.querySelectorAll("a, span");
|
||||
|
||||
links[0].textContent = metadata[0];
|
||||
if (links[0].nodeName == "A") {
|
||||
links[0].setAttribute("href", "#" + metadata[0]);
|
||||
}
|
||||
links[1].setAttribute("href", factoryUrl);
|
||||
links[2].setAttribute("href", factoryUrl + ".sig");
|
||||
links[3].setAttribute("href", updateUrl);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
await Promise.allSettled(requests);
|
||||
setTimeout(updateReleases, delayMs);
|
||||
}
|
||||
|
||||
setTimeout(updateReleases, delayMs);
|
||||
|
||||
// @license-end
|
@ -1,475 +0,0 @@
|
||||
// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT
|
||||
|
||||
import * as fastboot from "./fastboot/ffe7e270/fastboot.min.mjs";
|
||||
|
||||
const RELEASES_URL = "https://releases.grapheneos.org";
|
||||
|
||||
const CACHE_DB_NAME = "BlobStore";
|
||||
const CACHE_DB_VERSION = 1;
|
||||
|
||||
const Buttons = {
|
||||
UNLOCK_BOOTLOADER: "unlock-bootloader",
|
||||
DOWNLOAD_RELEASE: "download-release",
|
||||
FLASH_RELEASE: "flash-release",
|
||||
LOCK_BOOTLOADER: "lock-bootloader",
|
||||
REMOVE_CUSTOM_KEY: "remove-custom-key"
|
||||
};
|
||||
|
||||
const InstallerState = {
|
||||
DOWNLOADING_RELEASE: 0x1,
|
||||
INSTALLING_RELEASE: 0x2
|
||||
};
|
||||
|
||||
let wakeLock = null;
|
||||
|
||||
const requestWakeLock = async () => {
|
||||
try {
|
||||
wakeLock = await navigator.wakeLock.request("screen");
|
||||
console.log("Wake lock has been set");
|
||||
wakeLock.addEventListener("release", async () => {
|
||||
console.log("Wake lock has been released");
|
||||
});
|
||||
} catch (err) {
|
||||
// if wake lock request fails - usually system related, such as battery
|
||||
throw new Error(`${err.name}, ${err.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
const releaseWakeLock = async () => {
|
||||
if (wakeLock !== null) {
|
||||
wakeLock.release().then(() => {
|
||||
wakeLock = null;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// reacquires the wake lock should the visibility of the document change and the wake lock is released
|
||||
document.addEventListener("visibilitychange", async () => {
|
||||
if (wakeLock !== null && document.visibilityState === "visible") {
|
||||
await requestWakeLock();
|
||||
}
|
||||
});
|
||||
|
||||
// This wraps XHR because getting progress updates with fetch() is overly complicated.
|
||||
function fetchBlobWithProgress(url, onProgress) {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", url);
|
||||
xhr.responseType = "blob";
|
||||
xhr.send();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
xhr.onload = () => {
|
||||
resolve(xhr.response);
|
||||
};
|
||||
xhr.onprogress = (event) => {
|
||||
onProgress(event.loaded / event.total);
|
||||
};
|
||||
xhr.onerror = () => {
|
||||
reject(`${xhr.status} ${xhr.statusText}`);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function setButtonState({ id, enabled }) {
|
||||
const button = document.getElementById(`${id}-button`);
|
||||
button.disabled = !enabled;
|
||||
return button;
|
||||
}
|
||||
|
||||
class BlobStore {
|
||||
constructor() {
|
||||
this.db = null;
|
||||
}
|
||||
|
||||
async _wrapReq(request, onUpgrade = null) {
|
||||
return new Promise((resolve, reject) => {
|
||||
request.onsuccess = () => {
|
||||
resolve(request.result);
|
||||
};
|
||||
request.oncomplete = () => {
|
||||
resolve(request.result);
|
||||
};
|
||||
request.onerror = (event) => {
|
||||
reject(event);
|
||||
};
|
||||
|
||||
if (onUpgrade !== null) {
|
||||
request.onupgradeneeded = onUpgrade;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async init() {
|
||||
if (this.db === null) {
|
||||
this.db = await this._wrapReq(
|
||||
indexedDB.open(CACHE_DB_NAME, CACHE_DB_VERSION),
|
||||
(event) => {
|
||||
let db = event.target.result;
|
||||
db.createObjectStore("files", { keyPath: "name" });
|
||||
/* no index needed for such a small database */
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async saveFile(name, blob) {
|
||||
await this._wrapReq(
|
||||
this.db.transaction(["files"], "readwrite").objectStore("files").add({
|
||||
name: name,
|
||||
blob: blob,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async loadFile(name) {
|
||||
try {
|
||||
let obj = await this._wrapReq(
|
||||
this.db.transaction("files").objectStore("files").get(name)
|
||||
);
|
||||
return obj.blob;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async close() {
|
||||
this.db.close();
|
||||
}
|
||||
|
||||
async download(url, onProgress = () => {}) {
|
||||
let filename = url.split("/").pop();
|
||||
let blob = await this.loadFile(filename);
|
||||
if (blob === null) {
|
||||
console.log(`Downloading ${url}`);
|
||||
let blob = await fetchBlobWithProgress(url, onProgress);
|
||||
console.log("File downloaded, saving...");
|
||||
await this.saveFile(filename, blob);
|
||||
console.log("File saved");
|
||||
} else {
|
||||
console.log(
|
||||
`Loaded ${filename} from blob store, skipping download`
|
||||
);
|
||||
}
|
||||
|
||||
return blob;
|
||||
}
|
||||
}
|
||||
|
||||
class ButtonController {
|
||||
#map;
|
||||
|
||||
constructor() {
|
||||
this.#map = new Map();
|
||||
}
|
||||
|
||||
setEnabled(...ids) {
|
||||
ids.forEach((id) => {
|
||||
// Only enable button if it won't be disabled.
|
||||
if (!this.#map.has(id)) {
|
||||
this.#map.set(id, /* enabled = */ true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setDisabled(...ids) {
|
||||
ids.forEach((id) => this.#map.set(id, /* enabled = */ false));
|
||||
}
|
||||
|
||||
applyState() {
|
||||
this.#map.forEach((enabled, id) => {
|
||||
setButtonState({ id, enabled });
|
||||
});
|
||||
this.#map.clear();
|
||||
}
|
||||
}
|
||||
|
||||
let installerState = 0;
|
||||
|
||||
let device = new fastboot.FastbootDevice();
|
||||
let blobStore = new BlobStore();
|
||||
let buttonController = new ButtonController();
|
||||
|
||||
async function ensureConnected(setProgress) {
|
||||
if (!device.isConnected) {
|
||||
setProgress("Connecting to device...");
|
||||
await device.connect();
|
||||
}
|
||||
}
|
||||
|
||||
async function unlockBootloader(setProgress) {
|
||||
await ensureConnected(setProgress);
|
||||
|
||||
// Trying to unlock when the bootloader is already unlocked results in a FAIL,
|
||||
// so don't try to do it.
|
||||
if (await device.getVariable("unlocked") === "yes") {
|
||||
return "Bootloader is already unlocked.";
|
||||
}
|
||||
|
||||
setProgress("Unlocking bootloader...");
|
||||
try {
|
||||
await device.runCommand("flashing unlock");
|
||||
} catch (error) {
|
||||
// FAIL = user rejected unlock
|
||||
if (error instanceof fastboot.FastbootError && error.status === "FAIL") {
|
||||
throw new Error("Bootloader was not unlocked, please try again!");
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return "Bootloader unlocking triggered successfully.";
|
||||
}
|
||||
|
||||
const supportedDevices = ["tegu", "comet", "komodo", "caiman", "tokay", "akita", "husky", "shiba", "felix", "tangorpro", "lynx", "cheetah", "panther", "bluejay", "raven", "oriole", "barbet", "redfin", "bramble", "sunfish", "coral", "flame"];
|
||||
|
||||
const legacyQualcommDevices = ["sunfish", "coral", "flame"];
|
||||
|
||||
const day1SnapshotCancelDevices = ["tegu", "comet", "komodo", "caiman", "tokay", "akita", "husky", "shiba", "felix", "tangorpro", "lynx", "cheetah", "panther", "bluejay", "raven", "oriole", "barbet", "redfin", "bramble"];
|
||||
|
||||
function hasOptimizedFactoryImage(product) {
|
||||
return !legacyQualcommDevices.includes(product);
|
||||
}
|
||||
|
||||
async function getLatestRelease() {
|
||||
let product = await device.getVariable("product");
|
||||
if (!supportedDevices.includes(product)) {
|
||||
throw new Error(`device model (${product}) is not supported by the GrapheneOS web installer`);
|
||||
}
|
||||
|
||||
let metadataResp = await fetch(`${RELEASES_URL}/${product}-stable`);
|
||||
let metadata = await metadataResp.text();
|
||||
let releaseId = metadata.split(" ")[0];
|
||||
|
||||
return [`${product}-${hasOptimizedFactoryImage(product) ? "install" : "factory"}-${releaseId}.zip`, product];
|
||||
}
|
||||
|
||||
async function downloadRelease(setProgress) {
|
||||
await requestWakeLock();
|
||||
await ensureConnected(setProgress);
|
||||
|
||||
setProgress("Finding latest release...");
|
||||
let [latestZip,] = await getLatestRelease();
|
||||
|
||||
// Download and cache the zip as a blob
|
||||
setInstallerState({ state: InstallerState.DOWNLOADING_RELEASE, active: true });
|
||||
setProgress(`Downloading ${latestZip}...`);
|
||||
await blobStore.init();
|
||||
try {
|
||||
await blobStore.download(`${RELEASES_URL}/${latestZip}`, (progress) => {
|
||||
setProgress(`Downloading ${latestZip}...`, progress);
|
||||
});
|
||||
} finally {
|
||||
setInstallerState({ state: InstallerState.DOWNLOADING_RELEASE, active: false });
|
||||
await releaseWakeLock();
|
||||
}
|
||||
setProgress(`Downloaded ${latestZip} release.`, 1.0);
|
||||
}
|
||||
|
||||
async function reconnectCallback() {
|
||||
let statusField = document.getElementById("flash-release-status");
|
||||
statusField.textContent =
|
||||
"To continue flashing, reconnect the device by tapping here:";
|
||||
|
||||
let reconnectButton = document.getElementById("flash-reconnect-button");
|
||||
let progressBar = document.getElementById("flash-release-progress");
|
||||
|
||||
// Hide progress bar while waiting for reconnection
|
||||
progressBar.hidden = true;
|
||||
reconnectButton.hidden = false;
|
||||
|
||||
reconnectButton.onclick = async () => {
|
||||
await device.connect();
|
||||
reconnectButton.hidden = true;
|
||||
progressBar.hidden = false;
|
||||
};
|
||||
}
|
||||
|
||||
async function flashRelease(setProgress) {
|
||||
await requestWakeLock();
|
||||
await ensureConnected(setProgress);
|
||||
|
||||
// Need to do this again because the user may not have clicked download if
|
||||
// it was cached
|
||||
setProgress("Finding latest release...");
|
||||
let [latestZip, product] = await getLatestRelease();
|
||||
await blobStore.init();
|
||||
let blob = await blobStore.loadFile(latestZip);
|
||||
if (blob === null) {
|
||||
throw new Error("You need to download a release first!");
|
||||
}
|
||||
|
||||
setProgress("Cancelling any pending OTAs...");
|
||||
// Cancel snapshot update if in progress on devices which support it on all bootloader versions
|
||||
if (day1SnapshotCancelDevices.includes(product)) {
|
||||
let snapshotStatus = await device.getVariable("snapshot-update-status");
|
||||
if (snapshotStatus !== null && snapshotStatus !== "none") {
|
||||
await device.runCommand("snapshot-update:cancel");
|
||||
}
|
||||
}
|
||||
|
||||
setProgress("Flashing release...");
|
||||
setInstallerState({ state: InstallerState.INSTALLING_RELEASE, active: true });
|
||||
try {
|
||||
await device.flashFactoryZip(blob, true, reconnectCallback,
|
||||
(action, item, progress) => {
|
||||
let userAction = fastboot.USER_ACTION_MAP[action];
|
||||
let userItem = item === "avb_custom_key" ? "verified boot key" : item;
|
||||
setProgress(`${userAction} ${userItem}...`, progress);
|
||||
}
|
||||
);
|
||||
if (legacyQualcommDevices.includes(product)) {
|
||||
setProgress("Disabling UART...");
|
||||
// See https://android.googlesource.com/platform/system/core/+/eclair-release/fastboot/fastboot.c#532
|
||||
// for context as to why the trailing space is needed.
|
||||
await device.runCommand("oem uart disable ");
|
||||
setProgress("Erasing apdp...");
|
||||
// Both slots are wiped as even apdp on an inactive slot will modify /proc/cmdline
|
||||
await device.runCommand("erase:apdp_a");
|
||||
await device.runCommand("erase:apdp_b");
|
||||
setProgress("Erasing msadp...");
|
||||
await device.runCommand("erase:msadp_a");
|
||||
await device.runCommand("erase:msadp_b");
|
||||
}
|
||||
} finally {
|
||||
setInstallerState({ state: InstallerState.INSTALLING_RELEASE, active: false });
|
||||
await releaseWakeLock();
|
||||
}
|
||||
|
||||
return `Flashed ${latestZip} to device.`;
|
||||
}
|
||||
|
||||
async function eraseNonStockKey(setProgress) {
|
||||
await ensureConnected(setProgress);
|
||||
|
||||
setProgress("Erasing key...");
|
||||
try {
|
||||
await device.runCommand("erase:avb_custom_key");
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
throw error;
|
||||
}
|
||||
return "Key erased.";
|
||||
}
|
||||
|
||||
async function lockBootloader(setProgress) {
|
||||
await ensureConnected(setProgress);
|
||||
|
||||
setProgress("Locking bootloader...");
|
||||
try {
|
||||
await device.runCommand("flashing lock");
|
||||
} catch (error) {
|
||||
// FAIL = user rejected lock
|
||||
if (error instanceof fastboot.FastbootError && error.status === "FAIL") {
|
||||
throw new Error("Bootloader was not locked, please try again!");
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return "Bootloader locking triggered successfully.";
|
||||
}
|
||||
|
||||
function addButtonHook(id, callback) {
|
||||
let statusContainer = document.getElementById(`${id}-status-container`);
|
||||
let statusField = document.getElementById(`${id}-status`);
|
||||
let progressBar = document.getElementById(`${id}-progress`);
|
||||
|
||||
let statusCallback = (status, progress) => {
|
||||
if (statusContainer !== null) {
|
||||
statusContainer.hidden = false;
|
||||
}
|
||||
|
||||
statusField.className = "";
|
||||
statusField.textContent = status;
|
||||
|
||||
if (progress !== undefined) {
|
||||
progressBar.hidden = false;
|
||||
progressBar.value = progress;
|
||||
}
|
||||
};
|
||||
|
||||
let button = setButtonState({ id, enabled: true });
|
||||
button.onclick = async () => {
|
||||
try {
|
||||
let finalStatus = await callback(statusCallback);
|
||||
if (finalStatus !== undefined) {
|
||||
statusCallback(finalStatus);
|
||||
}
|
||||
} catch (error) {
|
||||
statusCallback(`Error: ${error.message}`);
|
||||
statusField.className = "error-text";
|
||||
await releaseWakeLock();
|
||||
// Rethrow the error so it shows up in the console
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function setInstallerState({ state, active }) {
|
||||
if (active) {
|
||||
installerState |= state;
|
||||
} else {
|
||||
installerState &= ~state;
|
||||
}
|
||||
invalidateInstallerState();
|
||||
}
|
||||
|
||||
function isInstallerStateActive(state) {
|
||||
return (installerState & state) === state;
|
||||
}
|
||||
|
||||
function invalidateInstallerState() {
|
||||
if (isInstallerStateActive(InstallerState.DOWNLOADING_RELEASE)) {
|
||||
buttonController.setDisabled(Buttons.DOWNLOAD_RELEASE);
|
||||
} else {
|
||||
buttonController.setEnabled(Buttons.DOWNLOAD_RELEASE);
|
||||
}
|
||||
|
||||
let disableWhileInstalling = [
|
||||
Buttons.DOWNLOAD_RELEASE,
|
||||
Buttons.FLASH_RELEASE,
|
||||
Buttons.LOCK_BOOTLOADER,
|
||||
Buttons.REMOVE_CUSTOM_KEY,
|
||||
];
|
||||
if (isInstallerStateActive(InstallerState.INSTALLING_RELEASE)) {
|
||||
buttonController.setDisabled(...disableWhileInstalling);
|
||||
} else {
|
||||
buttonController.setEnabled(...disableWhileInstalling);
|
||||
}
|
||||
|
||||
buttonController.applyState();
|
||||
}
|
||||
|
||||
function safeToLeave() {
|
||||
return installerState === 0;
|
||||
}
|
||||
|
||||
// This doesn't really hurt, and because this page is exclusively for web install,
|
||||
// we can tolerate extra logging in the console in case something goes wrong.
|
||||
fastboot.setDebugLevel(2);
|
||||
|
||||
fastboot.configureZip({
|
||||
workerScripts: {
|
||||
inflate: ["/js/fastboot/ffe7e270/vendor/z-worker-pako.js", "pako_inflate.min.js"],
|
||||
},
|
||||
});
|
||||
|
||||
if ("usb" in navigator) {
|
||||
addButtonHook(Buttons.UNLOCK_BOOTLOADER, unlockBootloader);
|
||||
addButtonHook(Buttons.DOWNLOAD_RELEASE, downloadRelease);
|
||||
addButtonHook(Buttons.FLASH_RELEASE, flashRelease);
|
||||
addButtonHook(Buttons.LOCK_BOOTLOADER, lockBootloader);
|
||||
addButtonHook(Buttons.REMOVE_CUSTOM_KEY, eraseNonStockKey);
|
||||
} else {
|
||||
console.log("WebUSB unavailable");
|
||||
}
|
||||
|
||||
// This will create an alert box to stop the user from leaving the page during actions
|
||||
window.addEventListener("beforeunload", event => {
|
||||
if (!safeToLeave()) {
|
||||
console.log("User tried to leave the page whilst unsafe to leave!");
|
||||
event.returnValue = "";
|
||||
}
|
||||
});
|
||||
|
||||
// @license-end
|
25
static/laptop.svg
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="1536"
|
||||
height="912"
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<path
|
||||
id="path1"
|
||||
d="M 141,0 C 116,0 96,20 96,45 v 750 c 0,25 20,45 45,45 H 33 C 15,840 0,855 0,873 v 6 c 0,18 15,33 33,33 h 1470 c 18,0 33,-15 33,-33 v -6 c 0,-18 -15,-33 -33,-33 h -108 c 25,0 45,-20 45,-45 V 45 c 0,-25 -20,-45 -45,-45 z m 28.19922,32 H 1366.8008 C 1389.6256,32 1408,50.374418 1408,73.199219 V 758.80078 C 1408,781.62558 1389.6256,800 1366.8008,800 H 169.19922 C 146.37442,800 128,781.62558 128,758.80078 V 73.199219 C 128,50.374418 146.37442,32 169.19922,32 Z"
|
||||
style="fill:#b3b3b3" />
|
||||
<rect
|
||||
width="384"
|
||||
height="16"
|
||||
x="576"
|
||||
y="-856"
|
||||
fill="#a5b5d3"
|
||||
ry="8"
|
||||
transform="scale(1,-1)"
|
||||
id="rect2"
|
||||
style="fill:#808080" />
|
||||
</svg>
|
After Width: | Height: | Size: 932 B |
BIN
static/logo.png
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 43 KiB |
@ -303,7 +303,7 @@ main.normalize {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.phone-logo-img {
|
||||
.laptop-logo-img {
|
||||
position: absolute;
|
||||
top: 48%;
|
||||
left: 50%;
|
||||
@ -498,11 +498,11 @@ details[open] summary {
|
||||
border-color: #222;
|
||||
}
|
||||
|
||||
.phone-img {
|
||||
.laptop-img {
|
||||
filter: brightness(0.87);
|
||||
}
|
||||
|
||||
.phone-logo-img {
|
||||
.laptop-logo-img {
|
||||
filter: invert(87%);
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 7.0 KiB |
BIN
static/oneko.gif
Normal file
After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 48 KiB |
51
static/package.html
Normal file
@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Package | Hakurei</title>
|
||||
<meta name="description" content="Overview of the planterette package manager and its interactions with Hakurei."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta property="og:title" content="Planterette packaging overview"/>
|
||||
<meta property="og:description" content="Overview of the planterette package manager and its interactions with Hakurei."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://hakurei.app/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="Hakurei logo"/>
|
||||
<meta property="og:site_name" content="Hakurei"/>
|
||||
<meta property="og:url" content="https://hakurei.app/package.html"/>
|
||||
<link rel="canonical" href="https://hakurei.app/package.html"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://port.mk/@hakurei"/>
|
||||
</head>
|
||||
<body>
|
||||
{% with current_page="package" %}
|
||||
{% include "header.html" %}
|
||||
{% endwith %}
|
||||
<main id="package">
|
||||
<h1><a href="#package">Package management</a></h1>
|
||||
|
||||
<p>Planterette is an experimental Android-like package manager providing
|
||||
fully self-contained apps running in Hakurei containers. The planterette
|
||||
software is not part of Hakurei and configures Hakurei through its public API.</p>
|
||||
|
||||
<p>Planterette is currently in a very early stage of development, and using it for
|
||||
anything beyond experimentation or development is not recommended.</p>
|
||||
|
||||
<p>If you wish to work on planterette, its source code can be found under
|
||||
<code>cmd/planterette</code> of Hakurei's source tree. This is subject to change.
|
||||
The Nix package builder can be accessed via the <code>buildPackage</code> output
|
||||
of the Nix flake, however this is pending replacement.</p>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
@ -1,42 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>PDF Viewer privacy policy | GrapheneOS</title>
|
||||
<meta name="description" content="Privacy policy for the GrapheneOS PDF Viewer app."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="PDF Viewer privacy policy"/>
|
||||
<meta property="og:description" content="Privacy policy for the GrapheneOS PDF Viewer app."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/pdfviewer-privacy-policy"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/pdfviewer-privacy-policy"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
</head>
|
||||
<body>
|
||||
{% include "header.html" %}
|
||||
<main id="pdfviewer-privacy-policy">
|
||||
<h1><a href="#pdfviewer-privacy-policy">PDF Viewer privacy policy</a></h1>
|
||||
<p>This app does not use any sensitive permissions, makes no internet connections and
|
||||
does not store any data other than preferences.</p>
|
||||
<p>See the <a href="https://github.com/GrapheneOS/PdfViewer">project's page on GitHub</a> for more information.</p>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
<svg width="276" height="579" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M18 0C9.163 0 2 7.163 2 16v547c0 8.837 7.163 16 16 16h240c8.837 0 16-7.163 16-16V16c0-8.837-7.163-16-16-16H18Zm2 6C11.163 6 4 13.163 4 22v537c0 8.837 7.163 16 16 16h236c8.837 0 16-7.163 16-16V22c0-8.837-7.163-16-16-16H20Z" fill="#979A97"/><path fill-rule="evenodd" clip-rule="evenodd" d="M20 3C11.163 3 4 10.164 4 19v541c0 8.837 7.163 16 16 16h236c8.837 0 16-7.163 16-16V19c0-8.837-7.163-16-16-16H20Zm7 7c-8.837 0-16 7.163-16 16v527c0 8.837 7.163 16 16 16h222c8.837 0 16-7.163 16-16V26c0-8.837-7.163-16-16-16H27Z" fill="#000"/><g filter="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M20 4C11.163 4 4 11.164 4 20v539c0 6.665 4.076 12.379 9.871 14.784C9.16 571 6 565.869 6 560V20c0-8.836 7.163-16 16-16h-2Zm234 0c8.837 0 16 7.163 16 16v540c0 5.869-3.16 11-7.871 13.784C267.924 571.379 272 565.665 272 559V20c0-8.837-7.163-16-16-16h-2Z" fill="#fff"/></g><circle cx="138.5" cy="26.5" r="7.5" fill="#000"/><circle cx="138.5" cy="26.5" r="5.5" fill="#0F1415"/><circle cx="138.5" cy="26.5" r="2.5" fill="#151E1E"/><circle cx="139.5" cy="27.5" r="1.5" fill="#1B2123"/><circle cx="139.5" cy="27.5" r=".5" fill="#3E4749"/><path d="M273 181a1 1 0 0 1 1-1h1a1 1 0 0 1 1 1v33a1 1 0 0 1-1 1h-1a1 1 0 0 1-1-1v-33ZM273 252a1 1 0 0 1 1-1h1a1 1 0 0 1 1 1v68a1 1 0 0 1-1 1h-1a1 1 0 0 1-1-1v-68Z" fill="#767676"/><defs><filter id="a" x="0" y="0" width="276" height="577.784" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur stdDeviation="2" result="effect1_foregroundBlur_6_67"/></filter></defs></svg>
|
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 13 KiB |
@ -1,2 +1,2 @@
|
||||
User-agent: *
|
||||
Sitemap: https://grapheneos.org/sitemap.xml
|
||||
Sitemap: https://hakurei.app/sitemap.xml
|
||||
|
@ -1,315 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: https://ogp.me/ns#">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Source code | GrapheneOS</title>
|
||||
<meta name="description" content="Source code for GrapheneOS."/>
|
||||
<meta name="theme-color" content="#212121"/>
|
||||
<meta name="color-scheme" content="dark light"/>
|
||||
<meta name="msapplication-TileColor" content="#ffffff"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
|
||||
<meta name="twitter:site" content="@GrapheneOS"/>
|
||||
<meta name="twitter:creator" content="@GrapheneOS"/>
|
||||
<meta property="og:title" content="GrapheneOS source code"/>
|
||||
<meta property="og:description" content="Source code for GrapheneOS."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
||||
<meta property="og:image:width" content="512"/>
|
||||
<meta property="og:image:height" content="512"/>
|
||||
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
||||
<meta property="og:site_name" content="GrapheneOS"/>
|
||||
<meta property="og:url" content="https://grapheneos.org/source"/>
|
||||
<link rel="canonical" href="https://grapheneos.org/source"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
||||
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
||||
[[css|/main.css]]
|
||||
<link rel="manifest" href="/manifest.webmanifest"/>
|
||||
<link rel="license" href="/LICENSE.txt"/>
|
||||
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
|
||||
</head>
|
||||
<body>
|
||||
{% with current_page="source" %}
|
||||
{% include "header.html" %}
|
||||
{% endwith %}
|
||||
<main id="source">
|
||||
<h1><a href="#source">Source code</a></h1>
|
||||
|
||||
<p>GrapheneOS is an <a href="https://opensource.org/osd">open source</a> project with
|
||||
an open development process.</p>
|
||||
|
||||
<p>The GrapheneOS sources are hosted in the
|
||||
<a href="https://github.com/GrapheneOS">GrapheneOS organization on GitHub</a>. Since
|
||||
there are many repositories, this page aims to provide a guide for it. See the
|
||||
<a href="/contact#reporting-issues">reporting issues section on the contact page</a>
|
||||
for an comparable overview of where issues should be filed.</p>
|
||||
|
||||
<nav id="table-of-contents">
|
||||
<h2><a href="#table-of-contents">Table of contents</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="#grapheneos">GrapheneOS</a></li>
|
||||
<li><a href="#standalone-apps">Standalone apps</a></li>
|
||||
<li><a href="#services">Services</a></li>
|
||||
<li><a href="#utilities">Utilities</a></li>
|
||||
<li><a href="#archive">Archive</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<section id="grapheneos">
|
||||
<h2><a href="#grapheneos">GrapheneOS</a></h2>
|
||||
|
||||
<p>The operating system source tree includes hundreds of repositories. Many of
|
||||
these are only used for debugging, testing or development and are not actually
|
||||
part of what gets used for building a production release. The manifest repository
|
||||
references all of these. Most of these are used unmodified from the Android Open
|
||||
Source Project (AOSP). A few dozen of the repositories including most of the core
|
||||
OS are either forked from AOSP or are unique to GrapheneOS.</p>
|
||||
|
||||
<p>The operating system has a unified build system, but some components like
|
||||
Chromium are too complex to fit into it so they're included as prebuilts instead
|
||||
of porting them to the AOSP build system. This is also done for developer
|
||||
convenience and bootstrapping, to avoid needing to build all the native /
|
||||
cross-compilation toolchains for each host and target platform combination, etc.
|
||||
The prebuilts can all be built from source if desired. The build instructions will
|
||||
be expanded to cover all of this in the future.</p>
|
||||
|
||||
<p>For a full list of the repositories in the OS source tree, look at the
|
||||
<a href="https://github.com/GrapheneOS/platform_manifest/blob/13/default.xml">default.xml
|
||||
list in the manifest repository</a>.</p>
|
||||
|
||||
<p>GrapheneOS forks of AOSP source tree repositories:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/device_common">device_common</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_generic_goldfish">device_generic_goldfish</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_akita">device_google_akita</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_bluejay">device_google_bluejay</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_caimito">device_google_caimito</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_comet">device_google_comet</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_felix">device_google_felix</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_gs-common">device_google_gs-common</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_gs101">device_google_gs101</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_gs101-sepolicy">device_google_gs101-sepolicy</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_gs201">device_google_gs201</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_gs201-sepolicy">device_google_gs201-sepolicy</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_lynx">device_google_lynx</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_pantah">device_google_pantah</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_raviole">device_google_raviole</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_shusky">device_google_shusky</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_tangorpro">device_google_tangorpro</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_tegu">device_google_tegu</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_zuma">device_google_zuma</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_zuma-sepolicy">device_google_zuma-sepolicy</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_zumapro">device_google_zumapro</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_zumapro-sepolicy">device_google_zumapro-sepolicy</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_configs">kernel_configs</a>: Base and recommended kernel configurations. The base configurations are enforced by the VTS and are modified to permit GrapheneOS changes.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_art">platform_art</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_bionic">platform_bionic</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_bootable_recovery">platform_bootable_recovery</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_build">platform_build</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_build_release">platform_build_release</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_build_soong">platform_build_soong</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_development">platform_development</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_external_boringssl">platform_external_boringssl</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_external_conscrypt">platform_external_conscrypt</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_external_selinux">platform_external_selinux</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_frameworks_base">platform_frameworks_base</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_frameworks_libs_systemui">platform_frameworks_libs_systemui</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_frameworks_native">platform_frameworks_native</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_frameworks_opt_net_wifi">platform_frameworks_opt_net_wifi</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_frameworks_opt_telephony">platform_frameworks_opt_telephony</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_hardware_google_pixel">platform_hardware_google_pixel</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_hardware_google_pixel-sepolicy">platform_hardware_google_pixel-sepolicy</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_hardware_interfaces">platform_hardware_interfaces</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_libcore">platform_libcore</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_manifest">platform_manifest</a>: Manifest for OS repositories</li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_Calendar">platform_packages_apps_Calendar</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_CellBroadcastReceiver">platform_packages_apps_CellBroadcastReceiver</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_Contacts">platform_packages_apps_Contacts</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_DeskClock">platform_packages_apps_DeskClock</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_Dialer">platform_packages_apps_Dialer</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_DocumentsUI">platform_packages_apps_DocumentsUI</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_EmergencyInfo">platform_packages_apps_EmergencyInfo</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_Gallery2">platform_packages_apps_Gallery2</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_Launcher3">platform_packages_apps_Launcher3</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_Nfc">platform_packages_apps_Nfc</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_Settings">platform_packages_apps_Settings</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_SettingsIntelligence">platform_packages_apps_SettingsIntelligence</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_StorageManager">platform_packages_apps_StorageManager</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_ThemePicker">platform_packages_apps_ThemePicker</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_WallpaperPicker2">platform_packages_apps_WallpaperPicker2</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_inputmethods_LatinIME">platform_packages_inputmethods_LatinIME</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_modules_adb">platform_packages_modules_adb</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_modules_AppSearch">platform_packages_modules_AppSearch</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_modules_Bluetooth">platform_packages_modules_Bluetooth</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_modules_common">platform_packages_modules_common</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_modules_ConfigInfrastructure">platform_packages_modules_ConfigInfrastructure</a></li>
|
||||
<li><a href="https://gitlab.com/grapheneos/platform_packages_modules_Connectivity">platform_packages_modules_Connectivity</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_modules_DnsResolver">platform_packages_modules_DnsResolver</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_modules_HealthFitness">platform_packages_modules_HealthFitness</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_modules_NetworkStack">platform_packages_modules_NetworkStack</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_modules_Permission">platform_packages_modules_Permission</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_modules_RemoteKeyProvisioning">platform_packages_modules_RemoteKeyProvisioning</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_modules_Uwb">platform_packages_modules_Uwb</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_modules_Virtualization">platform_packages_modules_Virtualization</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_modules_Wifi">platform_packages_modules_Wifi</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_providers_ContactsProvider">platform_packages_providers_ContactsProvider</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_providers_DownloadProvider">platform_packages_providers_DownloadProvider</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_providers_MediaProvider">platform_packages_providers_MediaProvider</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_services_Mms">platform_packages_services_Mms</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_services_Telecomm">platform_packages_services_Telecomm</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_services_Telephony">platform_packages_services_Telephony</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_system_core">platform_system_core</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_system_extras">platform_system_extras</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_system_librustutils">platform_system_librustutils</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_system_logging">platform_system_logging</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_system_netd">platform_system_netd</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_system_sepolicy">platform_system_sepolicy</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_system_vold">platform_system_vold</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_tools_metalava">platform_tools_metalava</a></li>
|
||||
</ul>
|
||||
|
||||
<p>GrapheneOS forks of AOSP kernel prebuilt repositories with the builds replaced with the GrapheneOS kernels built from the source repositories listed in the next section:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_raviole-kernels_6.1">device_google_raviole-kernels_6.1</a>: Pixel 6 and Pixel 6 Pro kernel prebuilts.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_bluejay-kernels_6.1">device_google_bluejay-kernels_6.1</a>: Pixel 6a kernel prebuilts.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_pantah-kernels_6.1">device_google_pantah-kernels_6.1</a>: Pixel 7 and Pixel 7 Pro kernel prebuilts.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_lynx-kernels_6.1">device_google_lynx-kernels_6.1</a>: Pixel 7a kernel prebuilts.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_tangorpro-kernels_6.1">device_google_tangorpro-kernels_6.1</a>: Pixel Tablet kernel prebuilts.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_felix-kernels_6.1">device_google_felix-kernels_6.1</a>: Pixel Fold kernel prebuilts.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_shusky-kernels_6.1">device_google_shusky-kernels_6.1</a>: Pixel 8 and Pixel 8 Pro kernel prebuilts.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_akita-kernels_6.1">device_google_akita-kernels_6.1</a>: Pixel 8a kernel prebuilts.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_caimito-kernels_6.1">device_google_caimito-kernels_6.1</a>: Pixel 9, Pixel 9 Pro and Pixel 9 Pro XL kernel prebuilts.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_comet-kernels_6.1">device_google_comet-kernels_6.1</a>: Pixel 9 Pro Fold kernel prebuilts.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/device_google_tegu-kernels_6.1">device_google_tegu-kernels_6.1</a>: Pixel 9a kernel prebuilts.</li>
|
||||
</ul>
|
||||
|
||||
<p>GrapheneOS forks of AOSP kernel repositories:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_manifest-6.1">kernel_manifest-6.1</a>: Kernel manifest for the Generic Linux 6.1 kernel.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_common-6.1">kernel_common-6.1</a>: Linux 6.1 LTS branch.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_manifest-6.6">kernel_manifest-6.6</a>: Kernel manifest for the Generic Linux 6.6 kernel.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_common-6.6">kernel_common-6.6</a>: Linux 6.6 LTS branch.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_manifest-6.12">kernel_manifest-6.12</a>: Kernel manifest for the Generic Linux 6.12 kernel.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_common-6.12">kernel_common-6.12</a>: Linux 6.12 LTS branch.</li>
|
||||
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_manifest-pixel">kernel_manifest-pixel</a>: Kernel manifest for the Pixel 6, Pixel 6 Pro, Pixel 6a, Pixel 7, Pixel 7 Pro, Pixel 7a, Pixel Tablet, Pixel Fold, Pixel 8, Pixel 8 Pro, Pixel 8a, Pixel 9, Pixel 9 Pro, Pixel 9 Pro XL and Pixel 9 Pro Fold.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_build">kernel_build</a>: Kernel build system for the Pixel 6, Pixel 6 Pro, Pixel 6a, Pixel 7, Pixel 7 Pro, Pixel 7a, Pixel Tablet, Pixel Fold, Pixel 8, Pixel 8 Pro, Pixel 8a, Pixel 9, Pixel 9 Pro, Pixel 9 Pro XL and Pixel 9 Pro Fold.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_devices_google_raviole">kernel_devices_google_raviole</a>: Kernel setup for the Pixel 6 and Pixel 6 Pro.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_devices_google_bluejay">kernel_devices_google_bluejay</a>: Kernel setup for the Pixel 6a.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_devices_google_pantah">kernel_devices_google_pantah</a>: Kernel setup for the Pixel 7 and Pixel 7 Pro.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_devices_google_lynx">kernel_devices_google_lynx</a>: Kernel setup for the Pixel 7a.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_devices_google_tangorpro">kernel_devices_google_tangorpro</a>: Kernel setup for the Pixel Tablet.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_devices_google_felix">kernel_devices_google_felix</a>: Kernel setup for the Pixel Fold.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_devices_google_akita">kernel_devices_google_akita</a>: Kernel setup for the Pixel 8a.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_devices_google_shusky">kernel_devices_google_shusky</a>: Kernel setup for the Pixel 8 and Pixel 8 Pro.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_devices_google_caimito">kernel_devices_google_caimito</a>: Kernel setup for the Pixel 9, Pixel 9 Pro and Pixel 9 Pro XL.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_devices_google_comet">kernel_devices_google_comet</a>: Kernel setup for the Pixel 9 Pro Fold.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_devices_google_tegu">kernel_devices_google_tegu</a>: Kernel setup for the Pixel 9a.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_google-modules_amplifiers">kernel_google-modules_amplifiers</a>: Kernel amplifier drivers for the Pixel 6, Pixel 6 Pro, Pixel 6a, Pixel 7, Pixel 7 Pro, Pixel 7a, Pixel Tablet, Pixel Fold, Pixel 8, Pixel 8 Pro, Pixel 8a, Pixel 9, Pixel 9 Pro, Pixel 9 Pro XL and Pixel 9 Pro Fold.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_google-modules_bms">kernel_google-modules_bms</a>: Kernel Battery Management System (BMS) driver for the Pixel 6, Pixel 6 Pro, Pixel 6a, Pixel 7, Pixel 7 Pro, Pixel 7a, Pixel Tablet, Pixel Fold, Pixel 8, Pixel 8 Pro, Pixel 8a, Pixel 9, Pixel 9 Pro, Pixel 9 Pro XL and Pixel 9 Pro Fold.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_google-modules_edgetpu_rio">kernel_google-modules_edgetpu_rio</a>: Kernel TPU driver for the Pixel 8, Pixel 8 Pro, Pixel 8a, Pixel 9, Pixel 9 Pro, Pixel 9 Pro XL and Pixel 9 Pro Fold.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_google-modules_gxp_gs201">kernel_google-modules_gxp_gs201</a>: Kernel GXP driver for the Pixel 7, Pixel 7 Pro, Pixel 7a, Pixel Tablet and Pixel Fold.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_google-modules_gxp_zuma">kernel_google-modules_gxp_zuma</a>: Kernel GXP driver for the Pixel 8, Pixel 8 Pro, Pixel 8a, Pixel 9, Pixel 9 Pro, Pixel 9 Pro XL and Pixel 9 Pro Fold.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_google-modules_power_reset">kernel_google-modules_power_reset</a>: Kernel reset driver for the Pixel 6, Pixel 6 Pro, Pixel 6a, Pixel 7, Pixel 7 Pro, Pixel 7a, Pixel Tablet, Pixel Fold, Pixel 8, Pixel 8 Pro, Pixel 8a, Pixel 9, Pixel 9 Pro, Pixel 9 Pro XL and Pixel 9 Pro Fold.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_google-modules_soc_gs">kernel_google-modules_soc_gs</a>: Kernel SoC driver for the Pixel 6, Pixel 6 Pro, Pixel 6a, Pixel 7, Pixel 7 Pro, Pixel 7a, Pixel Tablet, Pixel Fold, Pixel 8, Pixel 8 Pro, Pixel 8a, Pixel 9, Pixel 9 Pro, Pixel 9 Pro XL and Pixel 9 Pro Fold.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_google-modules_wlan_bcmdhd_bcm4383">kernel_google-modules_wlan_bcmdhd_bcm4383</a>: Kernel Wi-Fi/Bluetooth driver for the Pixel 8a.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_google-modules_wlan_bcmdhd_bcm4389">kernel_google-modules_wlan_bcmdhd_bcm4389</a>: Kernel Wi-Fi/Bluetooth driver for the Pixel 6, Pixel 6 Pro, Pixel 6a, Pixel 7, Pixel 7 Pro and Pixel Fold.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_google-modules_wlan_bcmdhd_bcm4390">kernel_google-modules_wlan_bcmdhd_bcm4390</a>: Kernel Wi-Fi/Bluetooth driver for the Pixel 9, Pixel 9 Pro, Pixel 9 Pro XL and Pixel 9 Pro Fold.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_google-modules_wlan_bcmdhd_bcm4398">kernel_google-modules_wlan_bcmdhd_bcm4398</a>: Kernel Wi-Fi/Bluetooth driver for the Pixel 8 and Pixel 8 Pro.</li>
|
||||
<li><a href="https://github.com/GrapheneOS/kernel_google-modules_wlan_syna_dhd43752p">kernel_google-modules_wlan_syna_dhd43752p</a>: Kernel Wi-Fi/Bluetooth driver for the Pixel Tablet.</li>
|
||||
</ul>
|
||||
|
||||
<p>Repositories added by GrapheneOS:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/adevtool">adevtool</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/branding">branding</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/hardened_malloc">hardened_malloc</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_external_AppStore">platform_external_AppStore</a>: App Store prebuilt</li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_external_Auditor">platform_external_Auditor</a>: Auditor app prebuilt</li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_external_Camera">platform_external_Camera</a>: Camera app prebuilt</li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_external_GmsCompatConfig">platform_external_GmsCompatConfig</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_external_Info">platform_external_Info</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_external_Messaging">platform_external_Messaging</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_external_PdfViewer">platform_external_PdfViewer</a>: PDF Viewer app prebuilt</li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_external_talkback">platform_external_talkback</a>: TalkBack app (GrapheneOS fork) prebuilt</li>
|
||||
<li><a href="https://gitlab.com/grapheneos/platform_external_vanadium">platform_external_vanadium</a>: Vanadium browser, WebView and library prebuilts</li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_AppCompatConfig">platform_packages_apps_AppCompatConfig</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_CarrierConfig2">platform_packages_apps_CarrierConfig2</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_ExactCalculator">platform_packages_apps_ExactCalculator</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_GmsCompat">platform_packages_apps_GmsCompat</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_LogViewer">platform_packages_apps_LogViewer</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_NetworkLocation">platform_packages_apps_NetworkLocation</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_Seedvault">platform_packages_apps_Seedvault</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_SetupWizard2">platform_packages_apps_SetupWizard2</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/platform_packages_apps_Updater">platform_packages_apps_Updater</a>: OS update client</li>
|
||||
<li><a href="https://github.com/GrapheneOS/script">script</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/vendor_state">vendor_state</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="standalone-apps">
|
||||
<h2><a href="#standalone-apps">Standalone apps</a></h2>
|
||||
|
||||
<p>These are standalone app projects developed by GrapheneOS and included in the
|
||||
OS. This does not include the many apps included by AOSP without modifications by
|
||||
GrapheneOS or with only minor modifications.</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/AppStore">App Store</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/Auditor">Auditor</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/Camera">Camera</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/Info">Info</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/Messaging">Messaging</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/PdfViewer">PDF Viewer</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS/talkback">talkback</a>: GrapheneOS fork of the open source TalkBack screen reader</li>
|
||||
<li><a href="https://github.com/GrapheneOS/Vanadium">Vanadium</a>: Privacy and security focused Chromium-based browser and WebView</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="services">
|
||||
<h2><a href="#services">Services</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/infrastructure">infrastructure</a>: Shared server infrastructure</li>
|
||||
<li><a href="https://github.com/GrapheneOS/AttestationServer">AttestationServer</a>: attestation.app remote attestation server</li>
|
||||
<li><a href="https://github.com/GrapheneOS/grapheneos.org">grapheneos.org</a>: Main website servers</li>
|
||||
<li><a href="https://github.com/GrapheneOS/releases.grapheneos.org">releases.grapheneos.org</a>: OS update and app repository servers</li>
|
||||
<li><a href="https://github.com/GrapheneOS/apps.grapheneos.org">apps.grapheneos.org</a>: Application repository</li>
|
||||
<li><a href="https://github.com/GrapheneOS/grapheneos.network">grapheneos.network</a>: Servers for HTTP/HTTPS connectivity checks, HTTPS network time, NTP (for Qualcomm XTRA), Broadcom PSDS cache, Samsung PSDS cache, Qualcomm PSDS (XTRA) cache, SUPL proxy, attestation key provisioning proxy and Vanadium component update check/download proxy</li>
|
||||
<li><a href="https://github.com/GrapheneOS/mail.grapheneos.org">mail.grapheneos.org</a>: Mail server</li>
|
||||
<li><a href="https://github.com/GrapheneOS/matrix.grapheneos.org">matrix.grapheneos.org</a>: Matrix and Element Web server</li>
|
||||
<li><a href="https://github.com/GrapheneOS/ns1.grapheneos.org">ns1.grapheneos.org</a>: Authoritative DNS servers</li>
|
||||
<li><a href="https://github.com/GrapheneOS/discuss.grapheneos.org">discuss.grapheneos.org</a>: Discussion forum server</li>
|
||||
<li><a href="https://github.com/GrapheneOS/grapheneos.social">grapheneos.social</a>: Mastodon instance</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="utilities">
|
||||
<h2><a href="#utilities">Utilities</a></h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/GrapheneOS/tls-pinning">tls-pinning</a>: Utilities for setting up conservative non-leaf TLS pinning with backup pins</li>
|
||||
<li><a href="https://github.com/GrapheneOS/branding-tools">branding-tools</a>: Scripting for generating branding</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section id="archive">
|
||||
<h2><a href="#archive">Archive</a></h2>
|
||||
|
||||
<p>An archive of legacy repositories is available via the
|
||||
<a href="https://github.com/GrapheneOS-Archive">GrapheneOS Archive</a>
|
||||
organization. This only covers repositories archives after renaming the project to
|
||||
GrapheneOS. Earlier code is mostly not available via GitHub anymore due to
|
||||
<a href="/history/#history">the unfortunate events</a> leading to the rename of
|
||||
the project.</p>
|
||||
</section>
|
||||
</main>
|
||||
{% include "footer.html" %}
|
||||
</body>
|
||||
</html>
|
1446
static/usage.html
@ -1,55 +0,0 @@
|
||||
<section id="{{codename}}">
|
||||
<h3><a href="#{{codename}}">{{name}}</a></h3>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Channel</th>
|
||||
<th>Version</th>
|
||||
<th>Downloads</th>
|
||||
</tr>
|
||||
<tr id="{{codename}}-stable">
|
||||
<td>Stable</td>
|
||||
{% if split %}
|
||||
<td><span>[[{{codename}}-stable-BUILD_NUMBER]]</span></td>
|
||||
{% else %}
|
||||
<td><a href="#[[{{codename}}-stable-BUILD_NUMBER]]">[[{{codename}}-stable-BUILD_NUMBER]]</a></td>
|
||||
{% endif %}
|
||||
<td>
|
||||
<ul>
|
||||
<li><a href="https://releases.grapheneos.org/{{codename}}-{{install | default("install")}}-[[{{codename}}-stable-BUILD_NUMBER]].zip">Install zip</a></li>
|
||||
<li><a href="https://releases.grapheneos.org/{{codename}}-{{install | default("install")}}-[[{{codename}}-stable-BUILD_NUMBER]].zip.sig">Install zip signature</a></li>
|
||||
<li><a href="https://releases.grapheneos.org/{{codename}}-ota_update-[[{{codename}}-stable-BUILD_NUMBER]].zip">Signed update package</a></li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="{{codename}}-beta">
|
||||
<td>Beta</td>
|
||||
{% if split %}
|
||||
<td><span>[[{{codename}}-beta-BUILD_NUMBER]]</span></td>
|
||||
{% else %}
|
||||
<td><a href="#[[{{codename}}-beta-BUILD_NUMBER]]">[[{{codename}}-beta-BUILD_NUMBER]]</a></td>
|
||||
{% endif %}
|
||||
<td>
|
||||
<ul>
|
||||
<li><a href="https://releases.grapheneos.org/{{codename}}-{{install | default("install")}}-[[{{codename}}-beta-BUILD_NUMBER]].zip">Install zip</a></li>
|
||||
<li><a href="https://releases.grapheneos.org/{{codename}}-{{install | default("install")}}-[[{{codename}}-beta-BUILD_NUMBER]].zip.sig">Install zip signature</a></li>
|
||||
<li><a href="https://releases.grapheneos.org/{{codename}}-ota_update-[[{{codename}}-beta-BUILD_NUMBER]].zip">Signed update package</a></li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="{{codename}}-alpha">
|
||||
<td>Alpha</td>
|
||||
{% if split %}
|
||||
<td><span>[[{{codename}}-alpha-BUILD_NUMBER]]</span></td>
|
||||
{% else %}
|
||||
<td><a href="#[[{{codename}}-alpha-BUILD_NUMBER]]">[[{{codename}}-alpha-BUILD_NUMBER]]</a></td>
|
||||
{% endif %}
|
||||
<td>
|
||||
<ul>
|
||||
<li><a href="https://releases.grapheneos.org/{{codename}}-{{install | default("install")}}-[[{{codename}}-alpha-BUILD_NUMBER]].zip">Install zip</a></li>
|
||||
<li><a href="https://releases.grapheneos.org/{{codename}}-{{install | default("install")}}-[[{{codename}}-alpha-BUILD_NUMBER]].zip.sig">Install zip signature</a></li>
|
||||
<li><a href="https://releases.grapheneos.org/{{codename}}-ota_update-[[{{codename}}-alpha-BUILD_NUMBER]].zip">Signed update package</a></li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</section>
|
@ -1,16 +1,7 @@
|
||||
<footer>
|
||||
<a href="/"><img src="[[path|/mask-icon.svg]]" width="512" height="512" alt=""/>GrapheneOS</a>
|
||||
<a href="/"><img src="[[path|/mask-icon.svg]]" width="512" height="512" alt=""/>Hakurei</a>
|
||||
<ul id="social">
|
||||
<li><a href="https://discuss.grapheneos.org/">Forum</a></li>
|
||||
<li><a href="https://discord.com/invite/grapheneos">Discord</a></li>
|
||||
<li><a href="https://t.me/GrapheneOS">Telegram</a></li>
|
||||
<li><a href="https://matrix.to/#/%23community:grapheneos.org">Matrix</a></li>
|
||||
<li><a href="/hiring">Hiring</a></li>
|
||||
<li><a href="https://x.com/GrapheneOS">X</a></li>
|
||||
<li><a href="https://grapheneos.social/@GrapheneOS">Mastodon</a></li>
|
||||
<li><a href="https://bsky.app/profile/grapheneos.org">Bluesky</a></li>
|
||||
<li><a href="https://github.com/GrapheneOS">GitHub</a></li>
|
||||
<li><a href="https://reddit.com/r/GrapheneOS">Reddit</a></li>
|
||||
<li><a href="https://www.linkedin.com/company/grapheneos/">LinkedIn</a></li>
|
||||
<li><a href="https://git.gensokyo.uk/security">Gitea</a></li>
|
||||
<li><a href="/discord">Discord</a></li>
|
||||
</ul>
|
||||
</footer>
|
||||
|
@ -1,18 +1,11 @@
|
||||
<header>
|
||||
<nav id="site-menu">
|
||||
<ul>
|
||||
<li {% if current_page == "/" %}aria-current="page"{% endif %}><a href="/"><img src="[[path|/mask-icon.svg]]" alt=""/>GrapheneOS</a></li>
|
||||
<li {% if current_page == "features" %}aria-current="page"{% endif %}><a href="/features">Features</a></li>
|
||||
<li {% if current_page == "install" %}aria-current="page"{% endif %}><a href="/install/">Install</a></li>
|
||||
<li {% if current_page == "build" %}aria-current="page"{% endif %}><a href="/build">Build</a></li>
|
||||
<li {% if current_page == "usage" %}aria-current="page"{% endif %}><a href="/usage">Usage</a></li>
|
||||
<li {% if current_page == "faq" %}aria-current="page"{% endif %}><a href="/faq">FAQ</a></li>
|
||||
<li {% if current_page == "releases" %}aria-current="page"{% endif %}><a href="/releases">Releases</a></li>
|
||||
<li {% if current_page == "source" %}aria-current="page"{% endif %}><a href="/source">Source</a></li>
|
||||
<li {% if current_page == "history" %}aria-current="page"{% endif %}><a href="/history/">History</a></li>
|
||||
<li {% if current_page == "articles" %}aria-current="page"{% endif %}><a href="/articles/">Articles</a></li>
|
||||
<li {% if current_page == "donate" %}aria-current="page"{% endif %}><a href="/donate">Donate</a></li>
|
||||
<li {% if current_page == "contact" %}aria-current="page"{% endif %}><a href="/contact">Contact</a></li>
|
||||
<li {% if current_page == "/" %}aria-current="page"{% endif %}><a href="/"><img src="[[path|/mask-icon.svg]]" alt=""/>Hakurei</a></li>
|
||||
<li {% if current_page == "package" %}aria-current="page"{% endif %}><a href="/package.html">Package</a></li>
|
||||
<li {% if current_page == "install" %}aria-current="page"{% endif %}><a href="/install.html">Install</a></li>
|
||||
<!-- <li {% if current_page == "faq" %}aria-current="page"{% endif %}><a href="/faq.html">FAQ</a></li> -->
|
||||
<li {% if current_page == "contact" %}aria-current="page"{% endif %}><a href="/contact.html">Contact</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|