Commit f713d4e9 authored by Clark's avatar Clark
Browse files

Removing unnecessary properties. Tocify should handle heading links

parent 9337ff5e
# -*- org-confirm-babel-evaluate: nil -*-
#+TITLE: App Server
#+DATE: 12/7/2019
#+TAGS: :blog:guides:debian:docker:traefik:api:
#+DESCRIPTION:
#+PROPERTY: header-args :cache yes
#+BEGIN_VERSE
......@@ -14,10 +12,6 @@ Deploy private apps on an internal server. Setup static networking that will be
Begin with =sudo test=.
* Debian 10 Images
:PROPERTIES:
:CUSTOM_ID: Debian_10_Images
:END:
Unfortunately, more often than not, I've found it necessary to use the unofficial version including support for non-free firmware for my machines.
......@@ -36,9 +30,6 @@ sudo dd if=~/debian-live-10.2.0-amd64-standard+nonfree.iso of=/dev/sda status=pr
Insert the USB, then boot from the flashed drive and proceed with installation. My default username is =user=.
* Sudo User Account
:PROPERTIES:
:CUSTOM_ID: Sudo_User_Account
:END:
Login as =user=. Then get *root*, once and nevermore, using =su -=. Grant sudo rights to =user=, then login again.
......@@ -66,9 +57,6 @@ sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.ta
#+END_SRC
* Static Networking
:PROPERTIES:
:CUSTOM_ID: Static_Networking
:END:
With a minimal server install, there are Setup static networking for the interface listed in =ip link show=. Ensure that interface, e.g. =eth0=, has the following configuration in =/etc/network/interfaces=.
......@@ -94,9 +82,6 @@ sudo /etc/init.d/networking restart
#+END_SRC
* Enable Firewalls
:PROPERTIES:
:CUSTOM_ID: Enable_Firewall
:END:
Install and enable firealls.
......@@ -127,9 +112,6 @@ echo "LABEL=data /data ext4 defaults 0 2" | sudo tee -a /etc/fstab && sudo mkdir
#+END_SRC
* Self-Signed Certificates
:PROPERTIES:
:CUSTOM_ID: Self-Signed_Certificates
:END:
I'll be using =X.509= to create a certificate with Subject Alternative Names for the internal sites.
......@@ -187,14 +169,8 @@ unset WEBSITE
#+END_SRC
* Docker Containers
:PROPERTIES:
:CUSTOM_ID: Docker_Containers
:END:
** Docker installation
:PROPERTIES:
:CUSTOM_ID: Docker_installation
:END:
Install packages needed to validate the security of the Docker package.
......@@ -222,9 +198,6 @@ sudo chmod +x /usr/local/bin/docker-compose
#+END_SRC
** Create config and run container
:PROPERTIES:
:CUSTOM_ID: Create_config_and_run_container
:END:
Setup environmental variables to be used in Compose, one of which is the hashed password (MD5/SHA1/Blowfish). For example, use =echo -n "mypassword" | sha1sum= to get the sha1 digest of the string /mypassword/.
......@@ -691,25 +664,16 @@ sudo docker-compose up -d --build --force-recreate
#+end_src
* Front End
:PROPERTIES:
:CUSTOM_ID: Front_End
:END:
This Docker container serves the following URLs, based on the =WEBSITE= variable from =/etc/compose/.env=.
** Traefik dashboard
:PROPERTIES:
:CUSTOM_ID: Traefik_dashboard
:END:
Accessible at https://traefik.WEBSITE, protected by the ={ADMIN_AUTH}= credentials defined in =/etc/compose/.env=.
This page presents the status of the various services controlled by Traefik.
** Nextcloud repository
:PROPERTIES:
:CUSTOM_ID: Nextcloud_repository
:END:
Accessible at https://cloud.WEBSITE.
......@@ -737,9 +701,6 @@ Enable several of the Nextcloud Apps - this provides a great opportunity to self
Check =https://cloud.WEBSITE/settings/admin/overview= for any additional security and setup warnings that may need to be addressed.
** Gitlab repository
:PROPERTIES:
:CUSTOM_ID: Gitlab_repository
:END:
This is a persistent repo - it will be restored if the Docker container is taken down, and subsequently brought up, accessible at https://git.WEBSITE.
......@@ -748,16 +709,10 @@ Visit the URL to setup the [default] =root= user account. Feel free to change th
Then setup a =Gitlab Runner=, at https://git.WEBSITE/admin/runners.
** Redmine project manager
:PROPERTIES:
:CUSTOM_ID: Redmine_project_manager
:END:
Redmine is a project management and issue tracking application. It's accessible at https://redmine.WEBSITE. Start by setting up Issue Statuses and Workflows that make sense for prospective Projects from https://redmine.WEBSITE/admin.
** Jupyter notebooks
:PROPERTIES:
:CUSTOM_ID: Jupyter_notebooks
:END:
This web app provides an environment to create persistent Jupyter notebooks using Python. This is accessible at https://jupyter.WEBSITE. Files created in the Jupyter web app will be stored on the local host at =/etc/compose/jupyter/code/=.
......@@ -768,9 +723,6 @@ The environment includes =Tensorflow= packages. To include packages for installa
=Voila=
** Adminer database management tool
:PROPERTIES:
:CUSTOM_ID: Adminer_database_management_tool
:END:
Accessible at https://adminer.WEBSITE, protected by the ={ADMIN_AUTH}= credentials defined in =/etc/compose/.env=.
......
# -*- org-confirm-babel-evaluate: nil -*-
#+TITLE: Public Server
#+DATE: 4/3/2020
#+TAGS: :blog:guides:debian:docker:traefik:apache:gitlab:gitlab-runner:runner:nextcloud:cloud:server:git:digitalocean:
#+DESCRIPTION:
#+PROPERTY: header-args :cache yes
#+BEGIN_VERSE
......@@ -21,9 +19,6 @@ I aspire to *self-host* as much as possible. Transparently though, I've chosen t
All-in, this runs me about $40/month.
** TODO DigitalOcean
:PROPERTIES:
:CUSTOM_ID: DigitalOcean
:END:
I'm using [[https://www.digitalocean.com/][DigitalOcean]] to host public facing services, like this blog, and a Nextcloud server that I use to stream music remotely.
......@@ -44,27 +39,15 @@ After opening a new account (requiring ID verification), create a new Project wi
Then click =Create Droplet=. After a few moments to deploy, the Droplet should appear online in the Project area. Click into the Droplet, add a 16 GB Volume named "[domain]-docker", and a separate 100 GB Volume named "[domain]-content", both manually formatted. These Volumes are easy to migrate between Droplets, are encrypted at rest, and easy to partition, so I prefer to place important or risky data in Volumes.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
DOES FLOATING IP WORK FOR PTR? SETTING UP DOMAIN PTR IS ACTUALLY PRIORITY!
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Then enable and assign a /Floating IP/ to the Droplet. Later I provide this Floating IP to my domain name manager (Namecheap). DigitalOcean allows me to reassign the Floating IP to another Droplet if desired, making it easy to perform a backup-restore or migration to another server without DNS disruption.
I reject DigitalOcean's offer to manage my DNS settings during Droplet setup. I prefer to separate these powers. Use =ssh [username]@[IPv4]= (not the /floating IP/) from the host that issued the *SSH key* to connect directly to the new server. I add this IP to my hosts file using =sudo bash -c 'printf "\n[IPv4] [Hostname] # DigitalOcean server" >> /etc/hosts'=, and then I can connect using =ssh root@[hostname]=.
** TODO ProtonMail
:PROPERTIES:
:CUSTOM_ID: ProtonMail
:END:
Not actually necessary for this guide, but I mention it...
** Namecheap
:PROPERTIES:
:CUSTOM_ID: Namecheap
:END:
Use [[https://www.namecheap.com/domains/registration/results/?type=beast&domain=][Namecheap's beast mode]] to search for a domain and buy it. Then harden your account with 2FA and security alerts at https://ap.www.namecheap.com/settings/security.
......@@ -79,16 +62,10 @@ Find the /Host Records/ on the *Advanced DNS* tab of the *Domain List* panel. Th
Also enable /WhoisGuard/ on the *Domain* tab, and purchase /PremiumDNS/ if you like.
* Initial configuration
:PROPERTIES:
:CUSTOM_ID: Initial_Configuration
:END:
Next, ssh to the server using *root*, for the last time ever.
** User Accounts
:PROPERTIES:
:CUSTOM_ID: User_Accounts
:END:
After logging in as =root=, I create a personal user named =user=, to match my local environment for convenience. You can replace =user= below as needed.
......@@ -109,9 +86,6 @@ exit
#+END_SRC
** Packages and firewall rules
:PROPERTIES:
:CUSTOM_ID: Packages_and_firewall_rules
:END:
Login using =ssh [hostname]=. Set the datetime to your preferred locale. Then install a few packages, updated daily using =unattanded-upgrades=. Finally configure strict firewall rules.
......@@ -186,9 +160,6 @@ exit
Going forward, connect to the server using =ssh -p 2222 [hostname]=. This is to leave port 22 for Gitlab usage.
** File system configuration
:PROPERTIES:
:CUSTOM_ID: File_system_configuration
:END:
DigitalOcean provides my 2 block storage Volumes with the names =sda= (16GB, attached first) and =sdb= (100GB, attached second), in addition to the Droplet block =vda=, per =lsblk=. I elected not to automatically mount the volumes so I can create several partitions, in addition to a swapfile, using the following. I named by Volumes =bytecache-docker= and =bytecache-content= during setup. You'll need to replace that below.
......@@ -262,16 +233,10 @@ sudo chown -R www-data:www-data /content/cloud/nextcloud
If there were no errors, =sudo reboot= once, and nevermore...
* Docker configuration
:PROPERTIES:
:CUSTOM_ID: Docker
:END:
I host the web services in a [[https://www.docker.com/][Docker]] container using the [[https://docs.traefik.io/][Traefik]] load-balancer.
** Docker installation
:PROPERTIES:
:CUSTOM_ID: Docker_installation
:END:
Install current version of Docker and Docker-Compose.
......@@ -488,9 +453,6 @@ sudo systemctl start docker
Configure applications that I'll be serving.
** Create Dockerfiles
:PROPERTIES:
:CUSTOM_ID: Create_Dockerfiles
:END:
Create custom Apache image and test homepage at =/content/blog/index.html=, so I will push updates to the blog remotely using =scp -P 2222 /var/www/html {user}@{IPv4}:/content/blog=, for example.
......@@ -517,9 +479,6 @@ sudo chown -R "${USER}":"${USER}" /content/blog
#+END_SRC
** TODO Create Compose file
:PROPERTIES:
:CUSTOM_ID: Create_Compose_file
:END:
Setup environmental variables to be used in Compose.
......@@ -1247,9 +1206,6 @@ EOT'
#+END_SRC
** Create Traefik config
:PROPERTIES:
:CUSTOM_ID: Create_Traefik_config
:END:
The [[https://docs.traefik.io/][Traefik load-balancer]] is the backbone of this public server. Much of the config is provided in these files.
......@@ -1558,6 +1514,13 @@ log_format = "json"
[session_server]
session_timeout = 1800
[[runners]]
name = "shell-runner"
url = "https://git.${DOMAIN}/"
token = "REPLACE_WITH_REAL_TOKEN"
executor = "shell"
EOT' && \
sudo chown -R "${USER}":"${USER}" /etc/compose/gitlab
#+END_SRC
......@@ -1585,9 +1548,6 @@ EOT'
#+END_SRC
** TODO Start and update containers
:PROPERTIES:
:CUSTOM_ID: Bring_up_container
:END:
Create a test webpage and empty files/directories with the appropriate permissions. Then bring up the Docker container.
......@@ -1607,9 +1567,6 @@ Most containers load pretty quickly, except for Gitlab - wait a few minutes.
* Post-deployment configuration
** TODO Gitlab repository
:PROPERTIES:
:CUSTOM_ID: Gitlab_repository
:END:
Accessible at https://git.DOMAIN.
......@@ -1683,25 +1640,16 @@ docker-compose --tlsverify --host "${DOCKER_HOST}" \
#+END_SRC
* TODO Front end
:PROPERTIES:
:CUSTOM_ID: Front_End
:END:
This Docker container serves the following URLs, based on the =DOMAIN= variable from =/etc/compose/.env=.
** Traefik dashboard
:PROPERTIES:
:CUSTOM_ID: Traefik_dashboard
:END:
Accessible at https://traefik.DOMAIN, protected by the ={ADMIN_AUTH}= credentials defined in =/etc/compose/.env=.
This page presents the status of the various services controlled by Traefik.
** Apache blog
:PROPERTIES:
:CUSTOM_ID: Apache_blog
:END:
Accessible at https://blog.DOMAIN.
......@@ -1714,9 +1662,6 @@ Accessible at https://registry.DOMAIN:5000.
Create a registry...
** TODO Nextcloud repository
:PROPERTIES:
:CUSTOM_ID: Nextcloud_repository
:END:
Accessible at https://cloud.DOMAIN. Visit the URL to setup the admin account. Elect to install the recommended apps at initialization - the integration script makes it simple.
......@@ -1739,9 +1684,6 @@ Visit https://cloud.{DOMAIN}/index.php/settings/admin to setup the /Email server
| Server address | smtp.{DOMAIN} : 587 |
** TODO Adminer database management tool
:PROPERTIES:
:CUSTOM_ID: Adminer_database_management_tool
:END:
Accessible at https://adminer.DOMAIN, protected by the ={ADMIN_AUTH}= credentials defined in =/etc/compose/.env=.
......
# -*- org-confirm-babel-evaluate: nil -*-
#+TITLE: Security Server
#+DATE: 12/6/2019
#+TAGS: :debian:docker:wazuh:openvas:arachnia:siem:vm:hids:dast:
#+DESCRIPTION:
#+PROPERTY: header-args :cache yes
#+BEGIN_VERSE
......@@ -14,10 +12,8 @@ Bootstrap a server to host the following:
This asset need be able to reach all other assets on the environment (outbound).
#+END_VERSE
* Debian 10 Images
:PROPERTIES:
:CUSTOM_ID: Debian_10_Images
:END:
[[https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/][Current and official Debian ISO files]].
......@@ -34,9 +30,6 @@ sudo dd if=~/debian-live-10.2.0-amd64-xfce+nonfree.iso of=/dev/sda status=progre
Insert the USB, then boot from the flashed drive and proceed with installation. My default username is =user=.
* Sudo User Account
:PROPERTIES:
:CUSTOM_ID: Sudo_User_Account
:END:
Login as =user=. Then get *root*, once and nevermore, using =su -=. Grant sudo rights to =user=, then login again.
......@@ -52,9 +45,6 @@ xfce4-session-logout -l
#+END_SRC
* Tor Package Management
:PROPERTIES:
:CUSTOM_ID: Tor_Package_Management
:END:
For privacy, I use Debian's onion services to download packages from official repositories. First though, this requires installing =tor= and =apt-transport-tor=.
......@@ -89,9 +79,6 @@ lynis flashrom xscreensaver yubikey-manager yubikey-personalization-gui keepassx
#+END_SRC
* Enable Firewalls
:PROPERTIES:
:CUSTOM_ID: Enable_Firewalls
:END:
First, login to the server from the host.
#+BEGIN_SRC sh
......@@ -147,14 +134,8 @@ sudo -i
#+END_SRC
* Docker Containers
:PROPERTIES:
:CUSTOM_ID: Docker_Containers
:END:
** Docker installation
:PROPERTIES:
:CUSTOM_ID: Docker_installation
:END:
Install packages needed to validate the security of the Docker package.
......@@ -184,14 +165,8 @@ chmod +x /usr/local/bin/docker-compose
#+END_SRC
** TODO Create Dockerfiles
:PROPERTIES:
:CUSTOM_ID: Create_Dockerfiles
:END:
*** Wazuh Dockerfiles
:PROPERTIES:
:CUSTOM_ID: Wazuh_Dockerfiles
:END:
Most of this is lifted from the official Wazuh Docker hub, with modifications to work inside a Traefik load-balancer handling SSL certificates.
......@@ -244,9 +219,6 @@ sed '$ a vm.max_map_count=262144' /etc/sysctl.conf
#+END_SRC
** TODO Create Compose file
:PROPERTIES:
:CUSTOM_ID: Create_Compose_file
:END:
Setup environmental variables to be used in Compose, one of which is the hashed password (MD5/SHA1/Blowfish). For example, use =echo -n "mypassword" | sha1sum= to get the sha1 digest of the string /mypassword/.
......@@ -511,11 +483,7 @@ EOT
#+END_SRC
** Bring up container
:PROPERTIES:
:CUSTOM_ID: Bring_up_container
:END:
Create a test webpage and empty files/directories with the appropriate permissions. Then bring up the Docker container.
......@@ -532,34 +500,22 @@ docker-compose up -d --build --force-recreate
#+END_SRC
* Front End
:PROPERTIES:
:CUSTOM_ID: Front_End
:END:
This Docker container serves the following URLs, based on the =WEBSITE= variable from =/etc/compose/.env=.
** Traefik dashboard
:PROPERTIES:
:CUSTOM_ID: Traefik_dashboard
:END:
Accessible at https://traefik.WEBSITE, protected by the ={ADMIN_AUTH}= credentials defined in =/etc/compose/.env=.
This page presents the status of the various services controlled by Traefik.
** Wazuh dashboard
:PROPERTIES:
:CUSTOM_ID: Wazuh_dashboard
:END:
Accessible at https://wazuh.WEBSITE, protected by the ={ADMIN_AUTH}= credentials defined in =/etc/compose/.env=.
This pages provides the dashboard for the [[https://wazuh.com/][Wazuh HIDS Security Platform]].
** Adminer database management tool
:PROPERTIES:
:CUSTOM_ID: Adminer_database_management_tool
:END:
Accessible at https://adminer.WEBSITE, protected by the ={ADMIN_AUTH}= credentials defined in =/etc/compose/.env=.
......
# -*- org-confirm-babel-evaluate: nil -*-
#+TITLE: Workstation
#+DATE: 11/30/2019
#+TAGS: :blog:guides:nextcloud:desktop:debian:xfce:git:emacs:vmware:python:jupyter:
#+DESCRIPTION:
#+PROPERTY: header-args :cache yes
#+BEGIN_VERSE
......@@ -10,9 +8,6 @@ This post describes how to bootstrap a general purpose desktop machine running D
#+END_VERSE
* Debian 10 Images
:PROPERTIES:
:CUSTOM_ID: Debian_10_Images
:END:
Unfortunately, more often than not, I've found it necessary to use the unofficial version including support for non-free firmware for my machines.
......@@ -32,9 +27,6 @@ sudo dd if=~/debian-live-10.2.0-amd64-xfce+nonfree.iso of=/dev/sda status=progre
Insert the USB, then boot from the flashed drive and proceed with installation. My default username is =user=.
* Sudo User Account
:PROPERTIES:
:CUSTOM_ID: Sudo_User_Account
:END:
Login as =user=. Then get *root*, once and nevermore, using =su -=. Grant sudo rights to =user=, then login again.
......@@ -50,17 +42,10 @@ xfce4-session-logout -l
#+END_SRC
* TODO Firmware updates
:PROPERTIES:
:CUSTOM_ID: Firmware_updates
:END:
My Lenovo Thinkpad requires some non-free firmware which, unfortunately, I need to enable for full functionality.
** TODO Graphics card
:PROPERTIES:
:CUSTOM_ID: Graphics_card
:END:
The graphics card is an NVIDIA Quadro M2200, which supports multiple monitors with the proper firmware. Download and install the latest driver (version 440.82 as of June 2020). Use [[https://www.nvidia.com/Download/index.aspx][this link]] to search for the latest driver or just install an older version and update it using =apt= (is this true????????).
......@@ -76,9 +61,6 @@ wget https://www.nvidia.com/content/DriverDownload-March2009/confirmation.php?ur
See here: https://www.linuxquestions.org/questions/linux-laptop-and-netbook-25/debian-10-buster-on-thinkpad-p51-nvidia-quadro-m2200-4175663184/
** TODO WiFi
:PROPERTIES:
:CUSTOM_ID: WiFi
:END:
See here: https://www.linuxquestions.org/questions/linux-laptop-and-netbook-25/debian-10-buster-on-thinkpad-p51-nvidia-quadro-m2200-4175663184/
......@@ -87,9 +69,6 @@ See here: https://www.linuxquestions.org/questions/linux-laptop-and-netbook-25/d
See here: https://www.linuxquestions.org/questions/linux-laptop-and-netbook-25/debian-10-buster-on-thinkpad-p51-nvidia-quadro-m2200-4175663184/
* TODO Tor Package Management
:PROPERTIES:
:CUSTOM_ID: Tor_Package_Management
:END:
For privacy, I use Debian's onion services to download packages from official repositories. First though, this requires installing =tor= and =apt-transport-tor=.
......@@ -126,9 +105,6 @@ sudo timedatectl set-timezone America/Los_Angeles
#+END_SRC
* Enable Firewalls
:PROPERTIES:
:CUSTOM_ID: Enable_Firewall
:END:
Install and enable firealls.
......@@ -138,9 +114,6 @@ sudo ufw --force enable
#+end_src
* Enforce VPN Routing
:PROPERTIES:
:CUSTOM_ID: Enforce_VPN_Routing
:END:
This requires some kind of VPN access. I'm using a low cost VPN provider, PIA. After signing up, the provide authentication credentials, what I'm using below as =vpn_username= and =vpn_password=.
......@@ -189,9 +162,6 @@ EOT'
#+END_SRC
* Wazuh Agent - Endpoint Security
:PROPERTIES:
:CUSTOM_ID: Wazuh_Agent_-_Endpoint_Security
:END:
Wazuh is an HIDS system, which is a fork of OSSEC built on the ELK stack. I'll install a Wazuh agent that I use to send data to a Wazuh server deployed elsewhere (e.g., on =10.0.0.2=).
......@@ -206,9 +176,6 @@ sudo WAZUH_MANAGER="192.168.1.2" apt install wazuh-agent -y
For addition steps registering agents to the Wazuh manager, see [[https://documentation.wazuh.com/3.9/user-manual/registering/index.html][the Wazuh guide]].
* Harden Firefox
:PROPERTIES:
:CUSTOM_ID: Harden_Firefox
:END:
Go through all the about:preferences particularly the /search/ and /privacy & security/ settings.
......@@ -221,9 +188,6 @@ Add and enable the following extensions, in the following order:
6) [[https://github.com/marcelklehr/floccus][Floccus]]
* Git
:PROPERTIES:
:CUSTOM_ID: Git
:END:
Live and die by Git. I'm using the handle =sentry=.
......@@ -249,9 +213,6 @@ Host *
#+end_src
* Emacs
:PROPERTIES:
:CUSTOM_ID: Emacs
:END:
Setup my preferred text editor, Emacs.
......@@ -282,9 +243,6 @@ sudo dpkg -i Whalebird-4.1.0-linux-x64.deb
* TODO Virtual Manager
* TODO VMware Workstation Pro
:PROPERTIES:
:CUSTOM_ID: VMware_Workstation_Pro
:END:
This requires virtualization enabled in the laptop's BIOS settings.
......@@ -297,9 +255,6 @@ sudo bash /tmp/vmware.bin
After a few minutes to download the files, a GUI will popup to complete the installation.
* Python 3
:PROPERTIES:
:CUSTOM_ID: Python_3
:END:
Install various libraries for Python.
......@@ -311,9 +266,6 @@ pip install virtualenv
#+END_SRC
* R
:PROPERTIES:
:CUSTOM_ID: R
:END:
Install R from CRAN.
......@@ -325,9 +277,6 @@ sudo apt install -y r-base
#+END_SRC
* GDB
:PROPERTIES:
:CUSTOM_ID: GDB
:END:
GDB is the GNU Project Debugger, facilitating low level analysis of executable programs by stepping through each operation. GDB comes with Debian, but I also install a few GDB utilities to enhance the debugging process.
......@@ -338,9 +287,6 @@ echo "source ~/peda/peda.py" >> ~/.gdbinit
#+END_SRC
* Radare 2
:PROPERTIES:
:CUSTOM_ID: Radare_2
:END:
Radare2 is a reverse engineering framework.
......@@ -350,9 +296,6 @@ r2pm init && \
r2pm -i rarop
#+END_SRC
* Bluetooth
:PROPERTIES:
:CUSTOM_ID: Bluetooth
:END:
I use =blueman=, as specified in the [[https://wiki.debian.org/BluetoothUser/a2dp][Debian Bluetooth setup guide]].
......@@ -366,9 +309,6 @@ sudo apt install -y blueman
#+end_src
* TODO Cell Phone Utilities
:PROPERTIES:
:CUSTOM_ID: Cell_Phone_Utilities
:END:
I have a Pixel 3 running the [[https://grapheneos.org/][GrapheneOS]]. To flash the OS to my cell phone, it requires =abd= and =fastboot=, which are not part of Debian. To add these utilities, I'll download and install the [[https://developer.android.com/studio/releases/platform-tools][Android SDK Platform-Tools]], as follows.
......