1 00:00:02,840 --> 00:00:03,840 ‫Next one up. 2 00:00:04,160 --> 00:00:05,029 ‫This is a big one. 3 00:00:05,030 --> 00:00:08,449 ‫Don't run your apps as root in the container 4 00:00:08,510 --> 00:00:09,510 ‫if you can avoid it. 5 00:00:10,352 --> 00:00:13,359 ‫If I do this real quick, on a little demo 6 00:00:13,360 --> 00:00:14,360 ‫here. 7 00:00:18,890 --> 00:00:21,260 ‫All right. I've got Docker running, 8 00:00:22,090 --> 00:00:23,449 ‫at least I should. All right. 9 00:00:24,020 --> 00:00:25,760 ‫And if I just run... 10 00:00:32,040 --> 00:00:35,249 ‫If I just run Nginx, right, and I do a 11 00:00:35,310 --> 00:00:36,959 ‫docker top on 12 00:00:38,860 --> 00:00:39,860 ‫that container. 13 00:00:41,310 --> 00:00:42,310 ‫What do we see here? 14 00:00:42,600 --> 00:00:45,929 ‫Inside the container, Nginx started 15 00:00:45,960 --> 00:00:48,990 ‫a process at root, and then it created 16 00:00:49,020 --> 00:00:52,049 ‫a new process as a non root 17 00:00:52,050 --> 00:00:53,160 ‫user. See how that user is 101. 18 00:00:54,559 --> 00:00:57,899 ‫This is common of a lot of daemon based programs 19 00:00:57,900 --> 00:00:59,730 ‫like MySQL, Postgres, Nginx. 20 00:01:00,330 --> 00:01:02,878 ‫A lot of them that aren't programming languages will 21 00:01:03,450 --> 00:01:05,430 ‫automatically do this. So, this is safe. 22 00:01:05,790 --> 00:01:08,459 ‫What this is doing is this is allowing 23 00:01:08,820 --> 00:01:11,417 ‫Nginx to spawn off worker processes that don't run as 24 00:01:11,790 --> 00:01:14,129 ‫root to do the majority of the work. 25 00:01:14,160 --> 00:01:17,159 ‫So, they have one master process that runs as root, but 26 00:01:17,160 --> 00:01:19,582 ‫that's not what's accepting connections and doing the 27 00:01:19,746 --> 00:01:21,560 ‫majority of the work. Most of that's in these worker 28 00:01:21,570 --> 00:01:24,659 ‫processes. They run as a normal user, which means if there 29 00:01:24,660 --> 00:01:27,300 ‫is a vulnerability in Nginx, chances are 30 00:01:28,230 --> 00:01:29,909 ‫when incoming connections are coming in and someone's 31 00:01:29,910 --> 00:01:32,333 ‫trying to exploit the Nginx HTTP protocol, 32 00:01:33,960 --> 00:01:36,809 ‫it's going to be locked, or jailed, into this user 33 00:01:36,810 --> 00:01:38,669 ‫at...most of the time unless there's a serious 34 00:01:38,670 --> 00:01:39,810 ‫vulnerability that's up here. 35 00:01:40,320 --> 00:01:43,319 ‫Down here, and then they're limited to what they can 36 00:01:43,320 --> 00:01:45,583 ‫do, right. Even if they were to take over that process 37 00:01:45,690 --> 00:01:47,790 ‫somehow, they're still limited as the user. 38 00:01:47,820 --> 00:01:48,820 ‫So, this is OK. 39 00:01:49,260 --> 00:01:51,661 ‫This is still not running as true root inside the 40 00:01:51,900 --> 00:01:54,791 ‫container. What I really am talking about is if you were to 41 00:01:54,840 --> 00:01:56,163 ‫run a Python app, or a Node 42 00:01:58,050 --> 00:01:59,939 ‫app, or something like that where it's a programing 43 00:01:59,940 --> 00:02:02,949 ‫language, then that's going to be 44 00:02:02,950 --> 00:02:05,057 ‫something that defaults to root because the 45 00:02:06,010 --> 00:02:08,859 ‫programming language in the container doesn't know how your 46 00:02:08,860 --> 00:02:11,259 ‫program works. It doesn't know what you want it to do. 47 00:02:11,530 --> 00:02:14,499 ‫So, it's going to do root by default, and 48 00:02:14,500 --> 00:02:17,020 ‫that's more about application compatibility. 49 00:02:18,070 --> 00:02:20,739 ‫We might say that we want this to be secure by default, but 50 00:02:20,740 --> 00:02:24,159 ‫Docker chose for all these official containers 51 00:02:24,160 --> 00:02:26,169 ‫to really run as root for the programming languages. 52 00:02:26,680 --> 00:02:27,680 ‫Let's go check that out. 53 00:02:31,127 --> 00:02:33,009 ‫Oops. Not that one. 54 00:02:33,940 --> 00:02:34,940 ‫Firefox. 55 00:02:36,610 --> 00:02:38,529 ‫So if we go, let's say, over to Hub. 56 00:02:40,406 --> 00:02:41,406 ‫Let's just do Node. 57 00:02:42,275 --> 00:02:44,751 ‫This is common of most languages. 58 00:02:45,070 --> 00:02:46,831 ‫I'm just going to pick Node as an example. 59 00:02:46,832 --> 00:02:47,832 ‫Inside Node, if 60 00:02:50,280 --> 00:02:53,159 ‫I go into one of the Dockerfiles here. 61 00:02:54,170 --> 00:02:56,100 ‫Then I search for user. 62 00:02:58,890 --> 00:03:00,598 ‫You'll notice that I don't actually find anything. 63 00:03:00,599 --> 00:03:02,840 ‫It's only this user add here. 64 00:03:03,180 --> 00:03:04,830 ‫You'll notice that it does this, right. 65 00:03:05,320 --> 00:03:08,340 ‫It's technically adding a group called Node 66 00:03:08,490 --> 00:03:10,229 ‫and it's adding a user called Node. 67 00:03:10,810 --> 00:03:14,259 ‫If you search the rest of this file, you realize that it 68 00:03:14,260 --> 00:03:16,939 ‫never changes to that user with the stanza U S E R, 69 00:03:17,870 --> 00:03:18,870 ‫right. 70 00:03:19,460 --> 00:03:22,050 ‫You should see user node in there somewhere as a line. 71 00:03:22,900 --> 00:03:24,749 ‫They don't do that because that's your job. 72 00:03:24,750 --> 00:03:26,759 ‫So, what you should be doing in your down 73 00:03:28,410 --> 00:03:30,550 ‫level Dockerfile. So, any Dockerfile you're creating off 74 00:03:32,160 --> 00:03:33,860 ‫of these official images for programming languages, 75 00:03:35,320 --> 00:03:37,819 ‫you should be taking advantage of the users they're 76 00:03:38,580 --> 00:03:41,489 ‫creating for you. If they're not creating those users, you 77 00:03:41,490 --> 00:03:43,639 ‫can create one yourself the same way. You can just steal 78 00:03:43,640 --> 00:03:46,237 ‫this little two-line thing and change to whatever the 79 00:03:47,220 --> 00:03:49,411 ‫user you want it to be. If it's for Python, you might just 80 00:03:49,412 --> 00:03:51,080 ‫call it Python user, whatever. 81 00:03:52,195 --> 00:03:54,559 ‫If you're doing that, then 82 00:03:55,490 --> 00:03:58,038 ‫the applications you run will not run as root in the 83 00:03:58,430 --> 00:03:59,509 ‫container. By default, 84 00:03:59,690 --> 00:04:02,475 ‫if you just run any standard Node app, it will use the root 85 00:04:02,720 --> 00:04:03,720 ‫user in a container. 86 00:04:04,220 --> 00:04:05,419 ‫Why is this so important? 87 00:04:05,810 --> 00:04:06,979 ‫Well, two things. 88 00:04:07,250 --> 00:04:09,619 ‫One, if someone is able to break through your application 89 00:04:09,620 --> 00:04:12,019 ‫and hack into your application and gain access to the file 90 00:04:12,020 --> 00:04:14,980 ‫system, if they...if that application is root, 91 00:04:15,590 --> 00:04:17,898 ‫then in the container, they can do whatever they want in 92 00:04:17,899 --> 00:04:19,819 ‫the container, right. They can write files to the file 93 00:04:19,820 --> 00:04:22,329 ‫system. They can install more programs in that container 94 00:04:22,330 --> 00:04:23,989 ‫that can run whenever they want in that container. 95 00:04:24,500 --> 00:04:26,389 ‫So, we really don't want them to do that. 96 00:04:26,660 --> 00:04:28,220 ‫We'd rather them be very limited. 97 00:04:28,430 --> 00:04:30,341 ‫So, if your applications support it, you 98 00:04:32,040 --> 00:04:35,009 ‫know, do this. You basically make sure that you have the 99 00:04:35,010 --> 00:04:36,060 ‫user available. 100 00:04:37,080 --> 00:04:39,950 ‫Then I have an example from DockerCon over here. 101 00:04:42,190 --> 00:04:44,974 ‫At DockerCon, I had a whole talk on Node.js, 102 00:04:45,960 --> 00:04:48,120 ‫and one of the topics was on the user. 103 00:04:48,251 --> 00:04:50,826 ‫Let me see if I can find that. 104 00:04:52,909 --> 00:04:54,899 ‫See what I did here? It is a pretty simple file. 105 00:04:55,210 --> 00:04:57,089 ‫I'm going to link this and put it in. 106 00:05:00,950 --> 00:05:01,950 ‫In this Dockerfile. 107 00:05:03,600 --> 00:05:05,910 ‫So, in this Dockerfile I have... 108 00:05:06,120 --> 00:05:08,339 ‫I didn't create a user because the Node image already 109 00:05:08,340 --> 00:05:11,183 ‫created it for me. I'm just changing to user node. 110 00:05:12,900 --> 00:05:15,959 ‫Then I'm installing my packages with these two lines, 111 00:05:16,350 --> 00:05:17,490 ‫and then later, I'm going to run it. 112 00:05:17,880 --> 00:05:19,612 ‫You'll notice that I have to start using the chown option 113 00:05:20,700 --> 00:05:23,760 ‫in my copy commands to make sure that my files 114 00:05:24,210 --> 00:05:27,132 ‫are now the same user as the user my 115 00:05:27,600 --> 00:05:29,371 ‫program will run as. Otherwise, there could be problems, 116 00:05:29,372 --> 00:05:30,372 ‫right. My application probably...if 117 00:05:32,340 --> 00:05:34,759 ‫it can't read the files, then it can't run it, right. 118 00:05:34,770 --> 00:05:36,079 ‫So, I need the changes those permissions. 119 00:05:36,090 --> 00:05:37,708 ‫I can do that with a one liner on a copy command. 120 00:05:39,790 --> 00:05:42,549 ‫You'll also see up here that I'm creating the directory and 121 00:05:42,550 --> 00:05:45,196 ‫chowning it as well so that whenever the app is copied 122 00:05:45,760 --> 00:05:48,099 ‫in, I just want to make sure, extra sure, that the 123 00:05:48,100 --> 00:05:50,200 ‫permissions are there so that it can write. 124 00:05:50,230 --> 00:05:52,827 ‫Because the minute I change this user, then this copy 125 00:05:53,260 --> 00:05:56,709 ‫command, or specifically this run command, will run 126 00:05:56,980 --> 00:05:59,136 ‫as that user. If it doesn't have permissions 127 00:06:00,160 --> 00:06:02,140 ‫to write to the directories, then it's also going to fail. 128 00:06:02,470 --> 00:06:04,929 ‫So, the reason that Docker doesn't do this for you is 129 00:06:04,930 --> 00:06:06,850 ‫because they know that your things will probably break. 130 00:06:07,120 --> 00:06:08,800 ‫So, you need to take these extra steps. 131 00:06:08,830 --> 00:06:10,179 ‫But, it's not that hard. It's really not. 132 00:06:10,450 --> 00:06:13,047 ‫You can probably do all of this testing in a day, and 133 00:06:13,420 --> 00:06:16,149 ‫then you'll want to run your systems through full CI and 134 00:06:16,150 --> 00:06:19,150 ‫full testing on your servers because sometimes, and PHP 135 00:06:19,660 --> 00:06:21,459 ‫is one of the ones that's bad at this. 136 00:06:21,780 --> 00:06:24,034 ‫PHP likes to run a bunch of log files and do a 137 00:06:24,760 --> 00:06:25,899 ‫bunch of writing to disk. 138 00:06:26,260 --> 00:06:29,151 ‫Really, anything that's allowing user uploads will write to 139 00:06:29,200 --> 00:06:31,269 ‫disk. So, you've got to make sure those permissions are 140 00:06:31,270 --> 00:06:33,999 ‫correct so that when people are writing files, like let's 141 00:06:34,000 --> 00:06:35,278 ‫say they're running a WordPress blog. 142 00:06:35,279 --> 00:06:38,519 ‫That WordPress blog will be writing to disk 143 00:06:38,560 --> 00:06:40,959 ‫when users upload images into their their blog. 144 00:06:41,380 --> 00:06:43,060 ‫You want to make sure those permissions are going to work. 145 00:06:43,090 --> 00:06:44,589 ‫So, you're going to have to definitely do some testing. 146 00:06:45,340 --> 00:06:48,220 ‫Once you've done that, now your application 147 00:06:48,460 --> 00:06:51,579 ‫will not run as root. So, it can't have full control 148 00:06:51,580 --> 00:06:54,459 ‫in the container. The other reason you want to do this 149 00:06:55,180 --> 00:06:58,240 ‫is if there's a vulnerability in Linux, which is rare, 150 00:06:58,870 --> 00:07:02,230 ‫or Docker, which is also very rare, then 151 00:07:02,530 --> 00:07:05,372 ‫there's less likelihood that they're going to break out of 152 00:07:05,410 --> 00:07:08,499 ‫this container. That's only happened, well, one 153 00:07:08,500 --> 00:07:11,319 ‫time that I'm very aware of, and I actually documented a 154 00:07:11,320 --> 00:07:12,320 ‫little bit of it down here. 155 00:07:13,880 --> 00:07:15,987 ‫Dirty COW. Dirty COW was a vulnerability in 156 00:07:16,930 --> 00:07:19,940 ‫Linux that allowed you to get out of 157 00:07:20,270 --> 00:07:21,270 ‫a container, 158 00:07:21,589 --> 00:07:24,559 ‫right. The changing of your 159 00:07:24,560 --> 00:07:25,560 ‫user 160 00:07:28,429 --> 00:07:30,259 ‫right here, wouldn't necessarily solve the entire problem, 161 00:07:30,530 --> 00:07:32,359 ‫but it certainly didn't hurt that problem. 162 00:07:32,420 --> 00:07:34,939 ‫Other vulnerabilities, it would probably protect against. 163 00:07:35,690 --> 00:07:37,279 ‫But this is a best practice. 164 00:07:37,370 --> 00:07:39,259 ‫I think that if you have a security team, they're kind of 165 00:07:39,260 --> 00:07:41,490 ‫going to insist that you don't run things as root. 166 00:07:41,840 --> 00:07:42,840 ‫So, 167 00:07:43,480 --> 00:07:43,959 ‫you would do that.