Check out a free preview of the full Complete Intro to Containers (feat. Docker) course
The "chroot" Lesson is part of the full, Complete Intro to Containers (feat. Docker) course featured in this preview video. Here's what you'd learn in this lesson:
Brian explains that chroot is a Linux kernel feature that allows the containment of processes, restricts a process to a certain file tree, and uses chroot to add bash commands to the bash directory. A chroot operation is necessary to understand how containers are layered to limit or deny access outside of a designated directory tree.
Transcript from the "chroot" Lesson
[00:00:00]
>> So a container, is kinda three different kernel features put together. One of them here is, I'm gonna say change root because every time I say cha-root, I feel ridiculous. But I know most people say that as cha-root. So that's one of the features. The next feature will be name spaces, and then the feature after that will be control cha-root or c-groups.
[00:00:25]
And these kind of three things combined together form a container. That's why I said there's no one idea of a single container. It's actually these three things put together, allow you to make a container. Okay? So let's start with the first and kind of most obvious problem, that if I have two people running processes on the same host operating system.
[00:00:47]
How can I make sure that they can't see each other's files. So if I download like my secret recipe unto my web server. I don't why has their secret recipe on their web server. Seems like a bad idea, but in this example they do. But I wanna make sure that no one else can see into the container.
[00:01:03]
And I don't want anyone inside of any other container to be able to see out to other ones. So that's what we're gonna do with change root or Linux jails. That's what these used to be called as you're jailing a process to a particular part of the operating system.
[00:01:21]
So, let's go ahead and give it a shot. So, by this point hopefully you have Docker installed. If not, please do that. I'm going to be doing this all within Docker. The reason being is that, I'm running right now on MacOS. And my MacOS doesn't have the same parameters, because it is not a Linux kernel, right?
[00:01:40]
It's a Unix based kernel, FreeBSD kind of stuff. So I'm actually going to be doing all these examples from within a Docker container. So I'm gonna be building containers within containers, like containers all the way down, nested virtualization as people like to call it. And you can do this too.
[00:01:59]
So I'm gonna copy this command right here. And I promise you by the end of this course, you will understand exactly what this particular thing is doing. But for now, just trust me that all this is gonna do is, it's gonna start up a Ubuntu container and then drop me inside of it.
[00:02:17]
Now you can do this with an iTerm. You can do this within any emulators you want to. But being on the VS code team, I'm gonna show you as much VS code as I possibly can get in here before they throw me out. Okay. I'm actually doing this within zsh.
[00:02:32]
But, this shouldn't make zero difference to you, you can be in zsh or bash. I tried this in bolt and all these commands will work both ways. So I copied again, wherever it was. This command right here, docker run- it -- name docker-host --rm -- privilege ubuntu : bionic.
[00:02:56]
Paste that in here. And it should, if you don't already have Ubuntu Bionic pulled, it will take a second to download. I think it's like 150-ish megabytes. It's my guess, I don't remember. You can see here now, I'm in this root at something. So if you say cat /etc/ Issue, it'll tell you that you are in Ubuntu 18.04 3 LTS.
[00:03:26]
This is a nice trick, cuz sometimes when you're in containers, you don't actually know which distribution in Linux you're in. This will tell you with across all distributions of Linux which one you're in. If you're using Linux directly, you don't have to drop into a container like this.
[00:03:43]
You can just do this all directly within Linux, same thing with WSL. If you're in Windows, then you're gonna have to probably do the same thing here. So I'm gonna switch over to my Windows computer really quick, just to show you that this actually can be done as well from PowerShell.
[00:03:58]
So I'm gonna open the Start bar here and I'm just gonna say PowerShell, which should open this. You can also do this within Windows Terminal, you can do this within VS Code. I'm just gonna show you from the PowerShell app directly, because I know all of you have it installed, because we installed it for you.
[00:04:13]
Well, let's actually do this within the Windows Terminal, but you now know where the PowerShell app is. So, I'm gonna take that send command that I copied and pasted on my Mac here in the Powershell, and I just paste that docker run -it --name docker-host --rm --privileged ubuntu:bionic.
[00:04:31]
And if I run that, you can see here. I'm in Ubuntu as well. So this will work within PowerShell. And actually for most of the course, this should work pretty well for you as well. Again, not a PowerShell person, I just want to show you that is available, that does work.
[00:04:52]
Okay, I'm gonna go back to Mac now. Back to the comfort of the computer that I know much better. So again in the solutions repo, I actually have a script that will run through all of these things for you, so that you can just run the script and it'll run everything for you.
[00:05:08]
But we're gonna type it by hand, because I think it's useful to create these things by hand. So our goal here, so you can see I can see my entire user system right now if I type ls. Which stands for list. I wanna get it so that I have a process that's limited to one folder within my particular operating system.
[00:05:29]
So I'm gonna make a new directory and say, my new root. Let's do that. So mkdir, means make directory. So you can see here now I have this my-new-root directory, so I'm going to CD into my-new-root. Nothing in here. Now the first thing I need to do is I need to, I can't just say chroot.bash.
[00:06:01]
So you have to tell it where do you want to be limited to, and then if you tell what to run afterwards, whether I wanna run a new shell inside of that. If I do this it's gonna say, I don't know where bash is, what is bash? Because there's no bash in here.
[00:06:16]
So you actually have to make a copy of the operating system inside of here, because once it's inside of here, you won't be calling outside of it. It literally can't. So it can't find bash, it can't find ls, it can't find all of these things that would normally be available.
[00:06:32]
So I can do that. So I can say, I'm gonna see it out here and say copy from bin/bash, let's see, I have to make a directory inside of my node. First I'm gonna say, mkdir inside of my-new-root/bin. And I'm saying copy from bin/bash, and I'm gonna copy that into my new root/bin/.
[00:06:59]
So now if I say ls my-new-root/bin, cool, now there's bash. So can I say, chroot my-new-root/ bash, cuz I still don't know what that is I don't I don't get it. Well, what am I gonna do about that? Well it turns out, that you need a certain amount of libraries.
[00:07:23]
Library code of modules that these particular processes and commands need to run. So if you type ldd. Bin/bash. You can see here, here's all the stuff it depends on. So you need to bring all the stuff with us. So I'm gonna make another two directories inside of my-new-root, and I'm gonna make one called lib.
[00:07:53]
And I also need to make one called lib 64. Now I could type out my new lib, lib 64 or I can get really clever and I can use curly brace. I can put a comma, which means one of them is just gonna be called lib. And then I would put another one called 64 like that.
[00:08:11]
So now if I go inside of my-new-root. You can see I have a lib and a lib64. Just some clever bash tricks for you. You can also just type out lib and then lib64 after that, it will work just as well. Makes sense? So, now we've seen this ldd up here for bash, so anything that doesn't have a path up here you can just ignore.
[00:08:33]
But these ones here that do have paths, we have to copy all of these into the correct directories inside of my-new-root. So I'm gonna say, copy, and then I'm just gonna copy and paste these. For this one, copy that. Copy that, copy that. And I'm gonna copy that into my-new-root/lib.
[00:09:02]
So now if I look inside of my-new-root inside of the lib, you can see here, it's got a bunch of stuff in there that I just copied over. Now we got one more here, that's gonna go into the lib64. You can tell cuz I'm just looking at where they are here.
[00:09:17]
And I'm just mimicking the same directory structure. Does that make sense? So I'm gonna copy that into lib64. So now if you look inside of lib64. We get that as well. And in case it's not obvious, lib64 is for 64 bit and the lib by implicitly would be 32 bits.
[00:09:42]
Which is how many bits the processes are. So now in theory, I should be able to say, change root my-new-root/ bash. And look. Now, I am inside of bash, inside of that directory. So if I type ls it's gonna say, I don't know what that is. Cuz you don't have anything else.
[00:10:11]
Some things are just built into the Linus kernel, so I can say pwd for what directory I'm in. You can see that I'm in the root directory of this particular project. And I can't really see much else. So, let's actually go and make it, so ls works as well so we can see what else is in our directory.
[00:10:29]
So if you type exit, that'll get you out of the cha-root environment. This will drop you back into Ubuntu. You can see here now I'm back in this. So now I'm just gonna say the same thing for, I'm gonna say copy /bin/ls and then I'm gonna copy that into my-new-root/ bin.
[00:10:50]
So now that's gonna copy ls in there, and I am gonna have to do the same thing for ldd /bin/ls. Same thing. You'll notice that a bunch of these are the same, that I've already copied some of them over. So let's just look inside of lib. So you can see here I haven't copied that one, so I have to copy that one.
[00:11:16]
So copy that into, that one I already have. You can see that there. so.2 I have that one. Looks like I need that one as well. Nope, nope. Yes, maybe, yes. So that one too. Or you could just copy all of them it wouldn't do any harm either hurts.
[00:11:37]
So that's going into my-new-root/lib. And then we'll look inside of my-new-root/lib64. And you can see here I'm gonna have to copy, not that one. Sorry, there. So, now I can go back into chroot my-new-root/ bash back in here and in theory, I should be able to say ls, and it couldn't find that one.
[00:12:07]
So let's go and make sure that that one is there as well, I missed one. That one right there. Very nice to tell me though, it's like I can't find this library. So copy that one into my-new-root/lib as well. And now, you can see, if I type ls, I can actually see what's inside of my directory.
[00:12:34]
But if you look inside of pwd, you can see it thinks it's at the most root directory. It cannot get out of this, so it has no concept what's going around it. It can only see inside of this. It's been jailed, or the root has been changed, hence the name cha-root
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops