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

推荐订阅源

Recent Commits to openclaw:main
Recent Commits to openclaw:main
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
S
Schneier on Security
T
The Exploit Database - CXSecurity.com
K
Kaspersky official blog
Cisco Talos Blog
Cisco Talos Blog
P
Privacy International News Feed
T
Tenable Blog
T
Threat Research - Cisco Blogs
Spread Privacy
Spread Privacy
V
Vulnerabilities – Threatpost
L
LINUX DO - 热门话题
T
The Blog of Author Tim Ferriss
WordPress大学
WordPress大学
P
Proofpoint News Feed
宝玉的分享
宝玉的分享
月光博客
月光博客
美团技术团队
N
Netflix TechBlog - Medium
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
NISL@THU
NISL@THU
G
Google Developers Blog
P
Privacy & Cybersecurity Law Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
I
Intezer
C
Cyber Attacks, Cyber Crime and Cyber Security
C
Cybersecurity and Infrastructure Security Agency CISA
MyScale Blog
MyScale Blog
C
CERT Recently Published Vulnerability Notes
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
L
Lohrmann on Cybersecurity
Recent Announcements
Recent Announcements
Project Zero
Project Zero
Latest news
Latest news
博客园_首页
C
Cisco Blogs
The Register - Security
The Register - Security
阮一峰的网络日志
阮一峰的网络日志
Simon Willison's Weblog
Simon Willison's Weblog
H
Help Net Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
AWS News Blog
AWS News Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Docker
Vercel News
Vercel News
Know Your Adversary
Know Your Adversary
罗磊的独立博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
云风的 BLOG
云风的 BLOG

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 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 35: Launching my VMs more reliably 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 41: Trying to understand what a bridge is
Julia Evans · 2021-01-19 · via Rc-2020 on Julia Evans

Hello! Yesterday I spent a lot of time trying to understand what a bridge is so here are my notes. I’m only going to talk about bridges as applied to container / VM networking because that’s what I’m trying to do and also I’ve also never seen a bridge used for anything else.

Some things in this post are almost certainly wrong.

why I’m doing this: trying to set up Firecracker networking

I’ve been setting up some VMs using AWS Firecracker (which is amazing and lets you start up VMs in like ONE SECOND, it’s extremely fast, and I will write about it in the future because I really love it). Yesterday morning I was trying to configure the VM’s networking so that I could connect to the outside internet from inside the VM. I was googling how to do it and there were all these references to “make a bridge”, so I figured I needed to use a bridge.

I’ve been avoiding understanding what a bridge is for years because it seemed confusing, but I copied and pasted some things from Github issues / various blog posts and none of them did what I wanted.

So I figured the “blindly copy and paste” approach wasn’t really going to work and decided OKAY TODAY IS THE DAY I WILL LEARN WHAT A BRIDGE IS.

I’m going to use a bunch of Docker examples in this post even though I’m not planning to use Docker because it’s already set up on my computer, it basically does what I want to do (but using a veth instead of a tap device), and I’m more familiar with it.

some blog posts that helped me

I asked on Twitter for help understanding Docker container networking and people linked me to 2 really good blog posts that helped me:

a bridge is a layer 2 network interface

One thing I learned is that a bridge is a layer 2 (ethernet) device that can have an arbitrary number of network interfaces attached to it.

My understanding of how it works is:

  1. You send a packet to the bridge
  2. If the bridge has a network interface attached to it with a MAC address matching the destination MAC address on your packet, it sends it to that network interface
  3. if there’s no matching interface or the packet is a broadcast packet (?) then it sends it to all of the interfaces

tap devices and veths are also layer 2 devices

Docker uses veth pairs and the VM setup I’m using right now is using taps. These are also both layer 2 network interfaces. So they just sort of send packets on blindly and something else is responsible for setting the correct MAC addresses on packets.

your computer finds container MAC addresses with ARP

One question I had was – if you’re sending a packet to a container and it needs to have the right MAC address on it to make it through the bridge, how does it know what the right MAC address is? I think the answer is the same as in a physical network: ARP!

So your computer sends an ARP request like “hey who’s 172.17.0.8” and the container sends an ARP reply back like “it’s me! here’s my MAC address”. The bridge gets involved here because it needs to send the ARP request to the container and the ARP reply back to the host.

I’m not 100% sure about this but I saw some ARP requests/replies being sent back and forth and it makes sense. I think this is really funny because – all of this information is on the same computer and it doesn’t feel like it should need to use ARP to look up MAC addresses, like it has all the information already! But I guess it just literally pretends like it’s a physical network.

you need to set up the route table correctly

I think the most important thing with bridges is to set up the route tables correctly. So far my understanding is that there are 2 route table entries you need to set:

route entry 1: on the host

The first route entry that needs to be set is on the host, to make sure that everything on the bridge subnet gets sent to the bridge. Here’s what that looks like in Docker’s default networking setup.

172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 

route entry 2: inside the container/VM

In the container/VM, the system’s gateway needs to be set to the bridge

For example, in a Docker container, you’ll see this:

$ ip route list
default via 172.17.0.1 dev eth0 
172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2 

This default via 172.17.0.1 dev eth0 line means that all packets going outside the container subnet should be first sent to 172.17.0.1, which is the docker0 bridge (actually it’s a veth pair which leads to the docker0 bridge)

you need an SNAT rule on the host

The third thing I need if I want the containers to be able to talk to the wider internet is an SNAT iptables rule on the host. Here’s what that looks like in Docker’s default setup.

$ sudo iptables-save
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE

now I can access the internet from my VM!

I’m still not 100% on bridges but I did manage to configure a bridge so that when I ssh into my Firecracker VM I can access the internet! I am extremely delighted by this.

Right now I’m reusing the docker0 bridge which I’ll probably stop doing, but it does work.

My understanding of all the steps to get a Docker-like setup where you can access a VM and it can access the outside internet are:

  1. create the VM network interface (either a tap device or a veth) (ip tuntap add dev "$TAP_DEV" mode tap)
  2. put the VM network interface behind the bridge (sudo brctl addif docker0 $TAP_DEV)
  3. bring up the VM network interface (ip link set dev "$TAP_DEV" up)
  4. set the VM’s gateway to be the bridge IP (via the kernel boot args, which I talk about below)
  5. setup the host’s route table to route packets on the bridge’s subnet to the bridge (I think I’d do this when creating the bridge, which I didn’t do in this case because I’m reusing the docker bridge)
  6. add an SNAT rule to the host to NAT packets coming out of the bridge (with iptables)
  7. Change /etc/resolv.conf to say nameserver 8.8.8.8 because I don’t have a working local resolver inside the VM

Here’s a snippet from my script that starts a firecracker VM. I modified it from the firecracker-demo code.

I might post the whole thing later after I clean it up and stop using the docker bridge.

CONTAINER_IP=172.17.0.33
GATEWAY_IP=172.17.0.1
DOCKER_MASK_LONG=255.255.255.0
ip tuntap add dev "$TAP_DEV" mode tap
sudo brctl addif docker0 $TAP_DEV
ip link set dev "$TAP_DEV" up
# I'm not sure what these two are for exactly
sysctl -w net.ipv4.conf.${TAP_DEV}.proxy_arp=1 > /dev/null
sysctl -w net.ipv6.conf.${TAP_DEV}.disable_ipv6=1 > /dev/null

I also had to set ip=${CONTAINER_IP}::${GATEWAY_IP}:${DOCKER_MASK_LONG}::eth0:off in the kernel boot args. to set the VM’s gateway.