惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Privacy & Cybersecurity Law Blog
Engineering at Meta
Engineering at Meta
Forbes - Security
Forbes - Security
MongoDB | Blog
MongoDB | Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
A
About on SuperTechFans
量子位
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
雷峰网
雷峰网
腾讯CDC
P
Proofpoint News Feed
S
Schneier on Security
S
Secure Thoughts
V
Visual Studio Blog
Help Net Security
Help Net Security
The Hacker News
The Hacker News
C
Cyber Attacks, Cyber Crime and Cyber Security
P
Privacy International News Feed
SecWiki News
SecWiki News
S
SegmentFault 最新的问题
T
Threatpost
小众软件
小众软件
MyScale Blog
MyScale Blog
F
Fortinet All Blogs
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
P
Proofpoint News Feed
T
Tailwind CSS Blog
I
Intezer
C
CERT Recently Published Vulnerability Notes
U
Unit 42
V
V2EX
Cyberwarzone
Cyberwarzone
Recorded Future
Recorded Future
O
OpenAI News
Project Zero
Project Zero
有赞技术团队
有赞技术团队
Google DeepMind News
Google DeepMind News
Last Week in AI
Last Week in AI
Hugging Face - Blog
Hugging Face - Blog
Know Your Adversary
Know Your Adversary
C
Cybersecurity and Infrastructure Security Agency CISA
Scott Helme
Scott Helme
V2EX - 技术
V2EX - 技术
博客园 - 叶小钗
S
Securelist
A
Arctic Wolf
The Cloudflare Blog
W
WeLiveSecurity
T
Threat Research - Cisco Blogs
博客园 - Franky

Rc-2020 on Julia Evans

Day 57: Trying to set up GitHub Actions Day 56: A little WebAssembly Day 53: a little nginx, IPv6, and wireguard Day 52: testing how many Firecracker VMs I can run Day 51: Fixed my logging and made a couple of puzzles Day 50: Building some tarballs for puzzles, and trying to make a kernel boot faster Day 49: making the VMs boot faster Day 48: Another Go program, and a little vim configuration Day 47: Using device mapper to manage Firecracker images Day 46: debugging an iptables problem Day 44: Building my VMs with Docker Day 43: Building VM images Day 42: Writing a Go program to manage Firecracker VMs Day 41: Trying to understand what a bridge is Day 40: screen flickering & a talk about containers Day 39: Customizing gotty's terminal Day 38: Modifying gotty to serve many different terminal applications at once Day 37: A new laptop and a little Vue Day 34: Learning about qemu Day 33: pairing is magic and beautiful git diffs Day 32: A Rails model that doesn't use the database with ActiveHash Day 24: a short talk about blogging myths, and a debugging tip Day 23: a little Rails testing Day 22: getting OAuth to work in Rails Day 21: wrangling systemd & setting up git deploys to a VM Day 19: Clustering faces (poorly) using an autoencoder Day 20: trying to figure out how Google Cloud IAM works Day 18: an answer to an autoencoder question Day 17: trying to wrap my head around autoencoders Day 13: BPTT, and debugging why a model isn't training is hard Day 11: learning about learning rates Day 10: Training an RNN to count to three Day 9: Generating a lot of nonsense with an RNN Day 8: Start with something that works Day 5: drawing lots of faces with sketch-rnn Day 3: an infinitely tall fridge Day 2: Rails associations & dragging divs around Day 1: a confusing Rails error message I'm doing another Recurse Center batch!
Day 35: Launching my VMs more reliably
Julia Evans · 2021-01-09 · via Rc-2020 on Julia Evans

I’ve been having a problem for a while where my virtual machines (that I use to set up the puzzles) don’t launch reliably – sometimes they work, and sometimes they don’t.

I didn’t understand why this was before, and on Friday I think I figured it out!

what was going wrong

When I started a puzzle, I’d:

  • launch a VM (by giving cloud-init a cloud-init.yaml file), which would set up all the right files and run some commands
  • wait until SSH was up
  • ssh into the VM and run a script called setup/run.sh
  • done!

I don’t know why it took me so long to remember this, but – just because ssh is running, it doesn’t mean that the cloud-init is done running! So if I ssh into the instance as soon as SSH is up, my setup script might not have everything it needs to run.

I also found this launchpad bug suggesting that at some point in the past cloud-init only brought up SSH when it was finished running, but that that doesn’t happen anymore.

solution: wait until cloud-init is done running

cloud-init makes this pretty easy: it creates a file at /var/lib/cloud/data/result.json when it’s done running.

I also made my puzzle setup code run as part of cloud-init (in the scripts/per-boot stage), so I don’t need to do an extra SSH to run the last stage of setup.

So now instead I’m doing:

  • launch a VM (by giving cloud-init a cloud-init.yaml file)
  • wait until SSH is up
  • wait until the result.json file is present
  • make sure that cloud-init succeeded
  • done!

I’m not sure that this will solve all my problems, but it’s helped already and it’s a much better plan.

how to make SSH ignore .ssh/known_hosts

Right now I’m testing my cloud-init.yaml files by spinning up a bunch of VMs on my laptop with qemu. I had a problem where every instance had a different randomly generated SSH key, so SSH was giving me these giant warnings about the key for ubuntu@localhost:2222 changing. These warnings were annoying me (and providing no value in this case) so I wanted them to go away.

At first I tried to solve this with ssh -o StrictHostKeyChecking=no but, while this let me SSH without typing “yes” to the prompt warning me about the change in keys, it still displayed the warning.

I found out that I can do ssh -o UserKnownHostsFile=/dev/null instead, which ignores my usual .ssh/known_hosts file.

a script to run my cloud-init files locally with qemu

I also wrote a script to run my cloud-init files locally!

Here it is. Now I can just run ./scripts/start-vm PUZZLE-NAME to start the VM for a given puzzle. It takes about a minute to boot a VM and it made it WAY WAY WAY faster to iterate on changes.

I’ve gotten a bit better at bash recently by writing the bash zine and I used some of my newfound bash knowledge here (like using trap to kill the qemu process when the script exits, writing while loops, and $(()) for arithmetic.). I felt like this was a nice example of a good place for a bash script because:

  • the logic is very simple (there’s just 1 while loop and a trap)
  • it needs to run a bunch of processes (so bash is the right language)
  • I’m the only person using it
#!/bin/bash
set -e
# kill qemu on exit
trap 'set -e; kill $(jobs -p)' exit

CLOUD_INIT_FILE=$(find . -path "*$1*cloud-init.yaml")
[ -f $CLOUD_INIT_FILE ] || exit

echo "instance-id: $(uuidgen || echo i-abcdefg)" > my-meta-data

IMG=/tmp/my-seed.img
FOCAL=/home/bork/work/images/focal-server-cloudimg-amd64.img
SNAPSHOT=/tmp/snapshot.qcow2
qemu-img create -b $FOCAL -f qcow2 -F qcow2 $SNAPSHOT

cloud-localds $IMG $CLOUD_INIT_FILE my-meta-data

qemu-system-x86_64 --enable-kvm -m 1024 \
    -drive file=$SNAPSHOT,format=qcow2 \
    -drive file=$IMG,format=raw \
    -net user,hostfwd=tcp::2222-:22 -net nic \
    -nographic > out 2>out &

SSH_OPTIONS="-p 2222 -i wizard.key -o UserKnownHostsFile=/dev/null -o ConnectTimeout=1 -o StrictHostKeyChecking=no"

start=$SECONDS
while ! ssh $SSH_OPTIONS wizard@localhost 'python3 /usr/local/bin/started_up'
do
    duration=$(( SECONDS - start ))
    echo "waiting for ssh.. $duration"
    sleep 1
done
# we're done! SSH into the VM.
ssh $SSH_OPTIONS wizard@localhost

next up: see if it’s actually more reliable!

I’ve done a lot of testing locally and this setup seems more reliable, but I still haven’t implemented it in production. My guess is that there are still a few other problems I’ll need to work out.

Booting a VM is also still pretty slow – it takes almost 2 minutes sometimes! Kamal suggested using kexec and I still haven’t fully understood what that is or how I could use it.