From 7e5960c14a0663c314fc7e5dee064b3fca89921a Mon Sep 17 00:00:00 2001 From: Joseph Montanaro Date: Sat, 14 May 2022 11:18:42 -0700 Subject: [PATCH] code formatting and docker lan post --- ...exposing-docker-containers-to-your-lan.svx | 43 +++++++ static/prism-dracula.css | 121 ++++++++++++++++++ static/style.css | 12 +- 3 files changed, 166 insertions(+), 10 deletions(-) create mode 100644 src/routes/_posts/exposing-docker-containers-to-your-lan.svx create mode 100644 static/prism-dracula.css diff --git a/src/routes/_posts/exposing-docker-containers-to-your-lan.svx b/src/routes/_posts/exposing-docker-containers-to-your-lan.svx new file mode 100644 index 0000000..3b4890d --- /dev/null +++ b/src/routes/_posts/exposing-docker-containers-to-your-lan.svx @@ -0,0 +1,43 @@ +--- +title: Exposing Docker Containers to your LAN +description: If, for some strange reason, you should want to do such a thing. +date: 2022-03-21 +--- + + +A while back I had occasion to make a number of docker containers directly accessible on the LAN, i.e. without all the usual ceremony of port-forwardism that Docker requires. In retrospect I made it a lot more complicated than it had to be, but I wanted to document the process anyway because you never know when that sort of thing might come in handy. + +## Aside: You Probably Don't Want This + +In my case, the reason for doing this was so that I could expose multiple difference services that all wanted to bind the same port. In other words, given that I was going to be hosting more than one HTTP-based application, I didn't want to have to remember (and type out all the time) a bunch of different ports to distinguish between the services I wanted to talk to. DNS is great, but it only points to IP addressesWell, SRV records can include ports, but browsers don't pay attention to those., after all. + +That said, had I only realized it at the time, there's a much better way to accomplish this than exposing entire containers to the LAN, and much less... questionable from a security standpoint: Just bind multiple IPs on the host. Docker allows you to specify what IP address to bind when forwarding a port to a container, so you can forward e.g. 192.168.50.21:80 to App 1, and 192.168.50.22:80 to App 2, and neither the apps nor the users need ever worry their pretty little heads about a thing. This is better than exposing the container directly - containerized applications generally expect to be pretty isolated from a networking point of view, with external traffic only hitting the one or two ports that they specify as their window to the outside world. So if some packaged application has to run its own Redis serverBecause some people just can't help jamming Redis into every app they write, it's like a spinal reflex or something., it might not take the extra step of only binding to localhost, and congratulations now anyone on the LAN can read your session cookies or whatever.Alternatively you can do what I did: Set up a _shared_ Redis server for a _bunch_ of different applications, in Docker of course, and then _knowingly_ expose that to the entire LAN, and damn the torpedoes. I cannot legally recommend this course of action. + +The caveat here is of course that you need to be sure the IP addresses you use aren't going to be stolen out from under you by somebody's iPad or something next time it connects to the network. This is easy if you control the DHCP server, and either easy or impossible if you don't. For reasons that I've never fully understood, but _probably_ boil down to leaving room for people to do exactly this sort of thing, many standard DHCP configurations assign IPs from just a portion of the available range. .100 is a common start point in a /24 network, so you can usually expect that .2-.99 will be available for you to work your will upon. + +The worse solution (exposing containers directly to the LAN) has this same caveat, so it's just worse in every way, there's really no advantage except that _maybe_ it's lower-overhead, since not as much forwarding of packets needs to take place. So yeah, probably just don't unless your containerized application _really needs_ Layer 2 access to the network, like it's an intrusion detection system and needs keep an eye on broadcast traffic or something. + +## Anyway + +With that all out of the way, having hopefully convinced you that this is almost never a good idea, here's how to do it: + +``` +docker network create \\ + -d ipvlan \\ + --subnet 192.168.50.0/24 \\ + --gateway 192.168.50.1 \\ + -o parent=eth0 \\ + lan + +docker run --network lan --ip 192.168.50.24 some/image:version +``` + +That's it! You're done, congratulations. (Obviously `--subnet`, `--gateway`, and `--parent` should be fed values appropriate to your network.) + +This isn't actually what the first draft of this post said. Initially I was going to suggest using the `macvlan` driver, and then go into a whole spiel about how if you do this and you also want the host to be able to talk to its containers, then you have to create _another_ (non-Docker-managed) `macvlan` interface in `bridge` mode, then route an IP range or two via that interface, as described [here](https://blog.oddbit.com/post/2018-03-12-using-docker-macvlan-networks/). + +`ipvlan` is a lot easier, though, and gives you almost exactly the same result. The only difference is that with `macvlan` Docker will actually make up a MAC address for the virtual interface and respond to ARP queries and so on with that. With `ipvlan` it just uses the host MAC. My suspicion is that this is probably another argument _for_ `ipvlan`, as I think I remember reading that multiple MAC addresses on one physical interface is considered a Bad Sign by some network watchdog types of things. + +So there you have it. You can dump containers on your LAN, and they will (from a networking standpoint) behave as if they were their own machines. But you probably don't want to. diff --git a/static/prism-dracula.css b/static/prism-dracula.css new file mode 100644 index 0000000..71c9437 --- /dev/null +++ b/static/prism-dracula.css @@ -0,0 +1,121 @@ +/** + * Dracula Theme originally by Zeno Rocha [@zenorocha] + * https://draculatheme.com/ + * + * Ported for PrismJS by Albert Vallverdu [@byverdu] + */ + +code[class*="language-"], +pre[class*="language-"] { + color: #f8f8f2; + background: none; + text-shadow: 0 1px rgba(0, 0, 0, 0.3); + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: 1em 0; + overflow: auto; + border-radius: 0.3em; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #282a36; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; + white-space: normal; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: #6272a4; +} + +.token.punctuation { + color: #f8f8f2; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.constant, +.token.symbol, +.token.deleted { + color: #ff79c6; +} + +.token.boolean, +.token.number { + color: #bd93f9; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin, +.token.inserted { + color: #50fa7b; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string, +.token.variable { + color: #f8f8f2; +} + +.token.atrule, +.token.attr-value, +.token.function, +.token.class-name { + color: #f1fa8c; +} + +.token.keyword { + color: #8be9fd; +} + +.token.regex, +.token.important { + color: #ffb86c; +} + +.token.important, +.token.bold { + font-weight: bold; +} + +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} diff --git a/static/style.css b/static/style.css index 91225cb..7c32838 100644 --- a/static/style.css +++ b/static/style.css @@ -64,20 +64,12 @@ code { background: #eee; border-radius: 0.2rem; font-family: Consolas, monospace; - font-size: 0.85rem; - padding: 0 0.15rem; -} - -pre { - padding: 0.5rem; - line-height: 1.1; - border-radius: 0.15rem; + font-size: 0.8rem; + padding: 0.05rem 0.2rem 0.1rem; } pre > code { - padding: 0; font-size: 0.8rem; - background-color: transparent; } /* TESTING */